Obtenga el último registro de la colección mongodb

99

Quiero saber el registro más reciente de una colección. ¿Como hacer eso?

Nota: sé que las siguientes consultas de línea de comando funcionan:

1. db.test.find().sort({"idate":-1}).limit(1).forEach(printjson);
2. db.test.find().skip(db.test.count()-1).forEach(printjson)

donde idate tiene la marca de tiempo agregada.

El problema es que más tiempo de recopilación es el momento de recuperar los datos y mi recopilación de "prueba" es realmente enorme. Necesito una consulta con respuesta en tiempo constante.

Si hay alguna consulta mejor en la línea de comandos de mongodb, hágamelo saber.

inkriti
fuente

Respuestas:

138

Esta es una repetición de la respuesta anterior, pero es más probable que funcione en diferentes versiones de mongodb.

db.collection.find().limit(1).sort({$natural:-1})
Dígitos
fuente
10
db.collection.find().limit(1).sort({$natural:-1}).pretty()si quieres que se vea bien
Anthony
Entonces, ¿cuál es la diferencia con este orden:db.collection.find().sort({$natural:-1}).limit(1).pretty()
Leo
@Digits qué impacto en el rendimiento tendrá si colocamos un límite al final y también cómo se obtiene el último registro cuando se limita la salida a un solo documento y debe ser el documento superior de la colección.
kailash yogeshwar
Buena respuesta. Intenté así: db.collection ("nombre de la colección"). Find ({}, {limit: 1}). Sort ({$ natural: -1})
Abdul Alim Shakir
Para cualquier persona que utilice AWS DocDB: Query failed with error code 303 and error message 'option $natural is not supported' on server docdb. Ojalá esa característica llegue pronto.
Marc
34

Esto le dará un último documento para una collection

db.collectionName.findOne({}, {sort:{$natural:-1}})

$natural:-1 significa orden opuesto al que se insertan los registros.

Editar : Para todos los votantes negativos, arriba hay una sintaxis de Mongoose, la sintaxis de CLI de mongo es:db.collectionName.find({}).sort({$natural:-1}).limit(1)

rubí oscuro
fuente
7
Tu sintaxis parece estar mal. No puedo hacer que funcione como lo tiene. Lo que sí funciona es: 'db.punchdeck.findOne ({$ query: {}, $ orderby: {$ natural: -1}})'
Dave Lowerre
no estoy seguro, por qué todos los votos negativos: este código funciona perfectamente para mí y es rápido
dark_ruby
2
@dark_ruby Tu consulta devuelve el error "$ err": "No se puede canonicalizar la consulta: BadValue Opción de proyección no admitida: ordenar: {$ natural: -1.0}",
Roman Podlinov
20

Necesito una consulta con respuesta en tiempo constante.

Por defecto, los índices en MongoDB son B-Trees. La búsqueda de un árbol B es una operación O (logN), por lo que incluso find({_id:...})no proporcionará respuestas O (1) de tiempo constante.

Dicho esto, también puede ordenar por _idsi está utilizando ObjectIdpara sus ID. Consulte aquí para obtener más detalles . Por supuesto, incluso eso solo es bueno hasta el último segundo.

Puede recurrir a "escribir dos veces". Escriba una vez en la colección principal y vuelva a escribir en una colección "actualizada por última vez". Sin transacciones esto no será perfecto, pero con un solo artículo en la colección "última actualización" siempre será rápido.

Vicepresidente de Gates
fuente
2
Veo muchas soluciones noSQL y MongoDB que abogan por "escribir dos veces", principalmente para los titulares de conteos cuando el tamaño de los datos se vuelve muy grande. ¿Supongo que esto es una práctica común?
Vinny
MongoDB no se descarga en el disco con mucha frecuencia y no tiene transacciones, por lo que las escrituras se vuelven significativamente más rápidas. La compensación aquí es que se le anima a desnormalizar los datos, lo que a menudo conduce a múltiples escrituras. Por supuesto, si obtiene un rendimiento de escritura de 10x o 100x (que he visto), entonces 2x o 3x las escrituras siguen siendo una gran mejora.
Vicepresidente de Gates
13

Otra forma más de obtener el último elemento de una colección MongoDB (no te preocupes por los ejemplos):

> db.collection.find().sort({'_id':-1}).limit(1)

Proyección normal

> db.Sports.find()
{ "_id" : ObjectId("5bfb5f82dea65504b456ab12"), "Type" : "NFL", "Head" : "Patriots Won SuperBowl 2017", "Body" : "Again, the Pats won the Super Bowl." }
{ "_id" : ObjectId("5bfb6011dea65504b456ab13"), "Type" : "World Cup 2018", "Head" : "Brazil Qualified for Round of 16", "Body" : "The Brazilians are happy today, due to the qualification of the Brazilian Team for the Round of 16 for the World Cup 2018." }
{ "_id" : ObjectId("5bfb60b1dea65504b456ab14"), "Type" : "F1", "Head" : "Ferrari Lost Championship", "Body" : "By two positions, Ferrari loses the F1 Championship, leaving the Italians in tears." }

Proyección ordenada (_id: orden inverso)

> db.Sports.find().sort({'_id':-1})
{ "_id" : ObjectId("5bfb60b1dea65504b456ab14"), "Type" : "F1", "Head" : "Ferrari Lost Championship", "Body" : "By two positions, Ferrari loses the F1 Championship, leaving the Italians in tears." }
{ "_id" : ObjectId("5bfb6011dea65504b456ab13"), "Type" : "World Cup 2018", "Head" : "Brazil Qualified for Round of 16", "Body" : "The Brazilians are happy today, due to the qualification of the Brazilian Team for the Round of 16 for the World Cup 2018." }
{ "_id" : ObjectId("5bfb5f82dea65504b456ab12"), "Type" : "NFL", "Head" : "Patriots Won SuperBowl 2018", "Body" : "Again, the Pats won the Super Bowl" }

sort({'_id':-1}), define una proyección en orden descendente de todos los documentos, en función de su _ids.

Proyección ordenada (_id: orden inverso): obtener el último (último) documento de una colección.

> db.Sports.find().sort({'_id':-1}).limit(1)
{ "_id" : ObjectId("5bfb60b1dea65504b456ab14"), "Type" : "F1", "Head" : "Ferrari Lost Championship", "Body" : "By two positions, Ferrari loses the F1 Championship, leaving the Italians in tears." }
ivanleoncz
fuente
2

php7.1 mongoDB:
$data = $collection->findOne([],['sort' => ['_id' => -1],'projection' => ['_id' => 1]]);

Sam
fuente
1

Mi solución :

db.collection("name of collection").find({}, {limit: 1}).sort({$natural: -1})

Abdul Alim Shakir
fuente
0

Si está utilizando identificadores de objeto Mongo generados automáticamente en su documento, contiene una marca de tiempo en los primeros 4 bytes con el último documento insertado en la colección. Entiendo que esta es una pregunta antigua, pero si alguien aún termina aquí buscando una alternativa más.

db.collectionName.aggregate(
[{$group: {_id: null, latestDocId: { $max: "$_id"}}}, {$project: {_id: 0, latestDocId: 1}}])

La consulta anterior daría el _id para el último documento insertado en la colección

Chan15
fuente
0

Así es como se obtiene el último registro de todos los documentos MongoDB de la colección "foo" (cambie foo, x, y, etc.)

db.foo.aggregate([{$sort:{ x : 1, date : 1 } },{$group: { _id: "$x" ,y: {$last:"$y"},yz: {$last:"$yz"},date: { $last : "$date" }}} ],{   allowDiskUse:true  })

puedes agregar o quitar del grupo

artículos de ayuda: https://docs.mongodb.com/manual/reference/operator/aggregation/group/#pipe._S_group

https://docs.mongodb.com/manual/reference/operator/aggregation/last/

ssymbiotik
fuente