En el caso de una colección grande, es mejor definir un índice en el agecampo. Entonces, si lo usa db.collection.find({}, {age: 1, _id:0}).sort({age:-1}).limit(1), probablemente tenga una consulta cubierta
Ali Dehghani
@AliDehghani ¿Funcionaría este método en fragmentos de mongo?
Cuando un $ sort precede inmediatamente a un $ limit , el optimizador puede fusionar el $ limit en el $ sort. Esto permite que la operación de clasificación solo mantenga los primeros n resultados a medida que avanza, donde n es el límite especificado , y MongoDB solo necesita almacenar n elementos en la memoria.
Modificado en la versión 4.0.
Entonces en el caso de
db.collection.find().sort({age:-1}).limit(1)
obtenemos solo el elemento más alto SIN ordenar la colección debido a la optimización mencionada.
ese enlace de documentación es para agregación. ¿Estás seguro de que find( ... ).sort( ... ).limit( ... )se trata de la misma forma que aggregate([{$match: ... }, {$sort: ...}, {$limit: ...}])? ¿Hay algún lugar en los documentos de Mongo en el que mencionen esto?
Esto no es tan eficiente como sort.limit. Aún así, sé que en el fondo todos se sienten extraños con ese tipo y límite ...
AFP_555
@ AFP_555 Realmente me sorprende saber que el agregado es más lento que una consulta de límite de clasificación. ¡Gracias por compartir!
Nam G VU
1
¿Es el agregado más lento que la consulta de límite de clasificación?
ashusvirus
1
Hago el caso de prueba simple. Crea una colección con 1.000.000 de documentos {nombre: "jugador", puntuación: x}. El .find (). Sort ({score: -1}). Limit (1); toma más tiempo que .aggregate ([{$ group: {_id: null, max: {$ max: "$ score"}}}])
tuananh
3
@tuananh, esto puede suceder si no tienes un índice de "puntuación". En este caso, sort tendrá que realizar operaciones O (n log n), mientras que el agregado solo hará un escaneo O (n). Con el campo indexado, sort (...). Limit (1) será una operación de tiempo constante O (1) muy rápida.
La otra respuesta similar no parece funcionar, esta sintaxis sí lo hace
Zach Smith
3
Amigos, pueden ver lo que está haciendo el optimizador ejecutando un plan. El formato genérico de buscar en un plan es de la documentación de MongoDB . es decir, Cursor.plan (). Si realmente desea profundizar, puede hacer un cursor.plan (verdadero) para obtener más detalles.
Dicho esto, si tiene un índice, su db.col.find (). Sort ({"field": - 1}). Limit (1) leerá una entrada de índice, incluso si el índice es ascendente predeterminado y desea la entrada máxima y un valor de la colección.
En otras palabras, las sugerencias de @yogesh son correctas.
Al menos en Mongo 4.2, esa sintaxis le dará un TypeError: db.collection.findOne(...).sort is not a function. collection.findOne () devuelve el documento en sí, por lo que llamar a sort () parece poco probable que funcione.
Peter Hansen
1
Explicación simple, si tiene una respuesta de consulta mongo como la siguiente, y solo desea el valor más alto de Array-> "Fecha"
Para un valor máximo, podemos escribir la consulta SQL como
select age from table_name order by age desc limit 1
de la misma manera también podemos escribir en mongodb.
db.getCollection('collection_name').find().sort({"age" : -1}).limit(1); //max age
db.getCollection('collection_name').find().sort({"age" : 1}).limit(1); //min age
db.collection.find().sort({age:-1}).limit(1)
Respuestas:
Como uno de los comentarios :
db.collection.find().sort({age:-1}).limit(1) // for MAX db.collection.find().sort({age:+1}).limit(1) // for MIN
es completamente utilizable pero no estoy seguro de su rendimiento
fuente
age
campo. Entonces, si lo usadb.collection.find({}, {age: 1, _id:0}).sort({age:-1}).limit(1)
, probablemente tenga una consulta cubiertaEl desempeño de la respuesta sugerida está bien. Según la documentación de MongoDB :
Entonces en el caso de
db.collection.find().sort({age:-1}).limit(1)
obtenemos solo el elemento más alto SIN ordenar la colección debido a la optimización mencionada.
fuente
find( ... ).sort( ... ).limit( ... )
se trata de la misma forma queaggregate([{$match: ... }, {$sort: ...}, {$limit: ...}])
? ¿Hay algún lugar en los documentos de Mongo en el que mencionen esto?¿qué pasa con el uso de marco agregado:
db.collection.aggregate({ $group : { _id: null, max: { $max : "$age" }}});
fuente
puedes usar group y max:
db.getCollection('kids').aggregate([ { $group: { _id: null, maxQuantity: {$max: "$age"} } } ])
fuente
Amigos, pueden ver lo que está haciendo el optimizador ejecutando un plan. El formato genérico de buscar en un plan es de la documentación de MongoDB . es decir, Cursor.plan (). Si realmente desea profundizar, puede hacer un cursor.plan (verdadero) para obtener más detalles.
Dicho esto, si tiene un índice, su db.col.find (). Sort ({"field": - 1}). Limit (1) leerá una entrada de índice, incluso si el índice es ascendente predeterminado y desea la entrada máxima y un valor de la colección.
En otras palabras, las sugerencias de @yogesh son correctas.
Gracias - Sumit
fuente
db.collection.findOne().sort({age:-1}) //get Max without need for limit(1)
fuente
TypeError: db.collection.findOne(...).sort is not a function
. collection.findOne () devuelve el documento en sí, por lo que llamar a sort () parece poco probable que funcione.Explicación simple, si tiene una respuesta de consulta mongo como la siguiente, y solo desea el valor más alto de Array-> "Fecha"
{ "_id": "57ee5a708e117c754915a2a2", "TotalWishs": 3, "Events": [ "57f805c866bf62f12edb8024" ], "wish": [ "Cosmic Eldorado Mountain Bikes, 26-inch (Grey/White)", "Asics Men's Gel-Nimbus 18 Black, Snow and Fiery Red Running Shoes - 10 UK/India (45 EU) (11 US)", "Suunto Digital Black Dial Unisex Watch - SS018734000" ], "Date": [ "2017-02-13T00:00:00.000Z", "2017-03-05T00:00:00.000Z" ], "UserDetails": [ { "createdAt": "2016-09-30T12:28:32.773Z", "jeenesFriends": [ "57edf8a96ad8f6ff453a384a", "57ee516c8e117c754915a26b", "58a1644b6c91d2af783770b0", "57ef4631b97d81824cf54795" ], "userImage": "user_profile/Male.png", "email": "[email protected]", "fullName": "Roopak Kapoor" } ], },
*** Entonces has añadido
algo como abajo
{ $project : { _id: 1, TotalWishs : 1 , wish:1 , Events:1, Wish_CreatedDate:1, Latest_Wish_CreatedDate: { $max: "$Date"}, } }
Y la respuesta de consulta final estará debajo
{ "_id": "57ee5a708e117c754915a2a2", "TotalWishs": 3, "Events": [ "57f805c866bf62f12edb8024" ], "wish": [ "Cosmic Eldorado Mountain Bikes, 26-inch (Grey/White)", "Asics Men's Gel-Nimbus 18 Black, Snow and Fiery Red Running Shoes - 10 UK/India (45 EU) (11 US)", "Suunto Digital Black Dial Unisex Watch - SS018734000" ], "Wish_CreatedDate": [ "2017-03-05T00:00:00.000Z", "2017-02-13T00:00:00.000Z" ], "UserDetails": [ { "createdAt": "2016-09-30T12:28:32.773Z", "jeenesFriends": [ "57edf8a96ad8f6ff453a384a", "57ee516c8e117c754915a26b", "58a1644b6c91d2af783770b0", "57ef4631b97d81824cf54795" ], "userImage": "user_profile/Male.png", "email": "[email protected]", "fullName": "Roopak Kapoor" } ], "Latest_Wish_CreatedDate": "2017-03-05T00:00:00.000Z" },
fuente
Para un valor máximo, podemos escribir la consulta SQL como
select age from table_name order by age desc limit 1
de la misma manera también podemos escribir en mongodb.
db.getCollection('collection_name').find().sort({"age" : -1}).limit(1); //max age db.getCollection('collection_name').find().sort({"age" : 1}).limit(1); //min age
fuente
También puede lograr esto a través de una canalización agregada.
db.collection.aggregate([{$sort:{age:-1}}, {$limit:1}])
fuente
O(n)
sin índices. Esto tiene una actuación deO(n log(n))