varios una registro modificar insertar eliminar documentos documento datos crear consultas comandos coleccion campo avanzadas mongodb spring-data spring-data-mongodb nosql

una - modificar registro mongodb



Usando Spring Data Mongodb, ¿es posible obtener el valor máximo de un campo sin tirar e iterar sobre una colección completa? (4)

Usando mongoTemplate.find() , especifico una consulta con la cual puedo llamar .limit() o .sort() :

.limit() devuelve un objeto Query
.sort() devuelve un objeto Sort

Dado esto, puedo decir Query (). Limit (int) .sort (), pero esto no realiza la operación deseada, simplemente ordena un conjunto de resultados limitado.

No puedo llamar a Query (). Sort (). Limit (int) ya que .sort () devuelve un Sort ()

Entonces, usando Spring Data, ¿cómo realizo lo siguiente como se muestra en el shell mongoDB? ¿Tal vez hay una manera de pasar una consulta en bruto que aún no he encontrado?

Estaría bien ampliar la interfaz de paginación si fuera necesario ... simplemente no parece ayudar. ¡Gracias!

> j = { order: 1 } { "order" : 1 } > k = { order: 2 } { "order" : 2 } > l = { order: 3 } { "order" : 3 } > db.test.save(j) > db.test.save(k) > db.test.save(l) > db.test.find() { "_id" : ObjectId("4f74d35b6f54e1f1c5850f19"), "order" : 1 } { "_id" : ObjectId("4f74d3606f54e1f1c5850f1a"), "order" : 2 } { "_id" : ObjectId("4f74d3666f54e1f1c5850f1b"), "order" : 3 } > db.test.find().sort({ order : -1 }).limit(1) { "_id" : ObjectId("4f74d3666f54e1f1c5850f1b"), "order" : 3 }


Normalmente, las cosas que se hacen con consultas SQL agregadas, se pueden abordar en (al menos) tres formas en las tiendas NoSQL:

  • con Mapa / Reducir. Esto está pasando por todos los registros, pero más optimizado (funciona con múltiples hilos y en clusters). Aquí está el tutorial de mapa / reducir para MongoDB.

  • precalcular el valor máximo en cada inserción y almacenarlo por separado. Entonces, cada vez que inserta un registro, lo compara con el valor máximo anterior, y si es mayor, actualice el valor máximo en el db.

  • buscar todo en la memoria y hacer el cálculo en el código. Esa es la solución más trivial. Probablemente funcione bien para pequeños conjuntos de datos.

Elegir uno sobre el otro depende de su uso de este valor máximo. Si se realiza con poca frecuencia, por ejemplo, para algunos informes de esquina, puede ir con el mapa / reducir. Si se usa con frecuencia, entonces almacene el máximo actual.


Por lo que yo sé, Mongo admite totalmente el género y el límite: ver http://www.mongodb.org/display/DOCS/Sorting+and+Natural+Order

Obtener el máximo / mínimo a través del mapa reducir va a ser muy lento y debe evitarse a toda costa.

No sé nada sobre Spring Data, pero puedo recomendar Morphia para ayudar con las consultas. De lo contrario, una forma básica con el controlador de Java sería:

DBCollection coll = db.getCollection("..."); DBCursor curr = coll.find(new BasicDBObject()).sort(new BasicDBObject("order", -1)) .limit(1); if (cur.hasNext()) System.out.println(cur.next());


Puedes hacer esto en sping-data-mongodb. Mongo optimizará las combinaciones de clasificación / límite SI el campo de clasificación está indexado (o el campo @Id). De lo contrario, sigue siendo bastante bueno porque usará un algoritmo top-k y evitará el género global ( mongodb sort doc) . Esto es del ejemplo de Mkyong, pero primero hago el tipo y establezco el límite en un segundo.

Query query = new Query(); query.with(new Sort(Sort.Direction.DESC, "idField")); query.limit(1); MyObject maxObject = mongoTemplate.findOne(query, MyObject.class);


Use la agregación $ max. Como $ max es un operador acumulador disponible solo en la etapa $ group, necesita hacer un truco. En el operador del grupo use cualquier constante como _id.
Tomemos el ejemplo dado en el sitio de Mongodb solamente -

Considere una colección de ventas con los siguientes documentos:

{ "_id" : 1, "item" : "abc", "price" : 10, "quantity" : 2, "date" : ISODate("2014-01-01T08:00:00Z") } { "_id" : 2, "item" : "jkl", "price" : 20, "quantity" : 1, "date" : ISODate("2014-02-03T09:00:00Z") } { "_id" : 3, "item" : "xyz", "price" : 5, "quantity" : 5, "date" : ISODate("2014-02-03T09:05:00Z") } { "_id" : 4, "item" : "abc", "price" : 10, "quantity" : 10, "date" : ISODate("2014-02-15T08:00:00Z") } { "_id" : 5, "item" : "xyz", "price" : 5, "quantity" : 10, "date" : ISODate("2014-02-15T09:05:00Z") }

Si quieres saber el precio máximo entre todos los artículos.

db.sales.aggregate( [ { $group: { _id: "1", //** This is the trick maxPrice: { $max: "$price" } } } ] )

Tenga en cuenta que el valor de "_id" - es "1". Puedes poner cualquier constante ...