mongodb cómo obtener el valor máximo de las colecciones


Respuestas:


119

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


9
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?
igonejack

68

El desempeño de la respuesta sugerida está bien. Según la documentación de MongoDB :

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.


6
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?
jmmut

25

¿qué pasa con el uso de marco agregado:

db.collection.aggregate({ $group : { _id: null, max: { $max : "$age" }}});

18
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.
cababunga


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.

Gracias - Sumit


2
db.collection.findOne().sort({age:-1}) //get Max without need for limit(1)

4
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"

{
  "_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": "roopak@small-screen.com",
      "fullName": "Roopak Kapoor"
    }
  ],

},

*** Entonces has añadido

Latest_Wish_CreatedDate: {$ max: "$ Date"},

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": "roopak@small-screen.com",
      "fullName": "Roopak Kapoor"
    }
  ],
  "Latest_Wish_CreatedDate": "2017-03-05T00:00:00.000Z"
},

1

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

0

También puede lograr esto a través de una canalización agregada.

db.collection.aggregate([{$sort:{age:-1}}, {$limit:1}])

3
Esto tiene un rendimiento terrible. Obtener el valor más alto siempre cuesta O(n)sin índices. Esto tiene una actuación deO(n log(n))
sb27
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.