Ottieni l'ultimo record dalla raccolta mongodb


99

Voglio conoscere il record più recente di una raccolta. Come farlo?

Nota: so che le seguenti query dalla riga di comando funzionano:

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

dove idate ha aggiunto il timestamp.

Il problema è più lungo, la raccolta è il tempo per recuperare i dati e la mia raccolta "di prova" è davvero enorme. Ho bisogno di una query con una risposta nel tempo costante.

Se esiste una query da riga di comando mongodb migliore, fammelo sapere.

Risposte:


138

Questo è un rimaneggiamento della risposta precedente ma è più probabile che funzioni su diverse versioni di mongodb.

db.collection.find().limit(1).sort({$natural:-1})

10
db.collection.find().limit(1).sort({$natural:-1}).pretty()se vuoi che sia carino
Anthony

Allora, qual è la differenza con questo ordine:db.collection.find().sort({$natural:-1}).limit(1).pretty()
Leone

@Digits quale impatto sulle prestazioni avrà se mettiamo un limite alla fine anche di come l'ultimo record viene recuperato quando stai limitando l'output a un solo documento e deve essere il primo documento nella raccolta.
kailash yogeshwar

Bella risposta. Ho provato in questo modo: db.collection ("name of collection"). Find ({}, {limit: 1}). Sort ({$ natural: -1})
Abdul Alim Shakir

Per coloro che utilizzano AWS DocDB: Query failed with error code 303 and error message 'option $natural is not supported' on server docdb. Si spera che questa funzionalità arrivi presto.
Marc

34

Questo ti darà un ultimo documento per un file collection

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

$natural:-1 significa ordine opposto a quello in cui sono inseriti i record.

Modifica : per tutti i downvoters, sopra è una sintassi Mongoose, la sintassi della CLI di mongo è:db.collectionName.find({}).sort({$natural:-1}).limit(1)


7
La tua sintassi sembra essere sbagliata. Non riesco a farlo funzionare come lo hai tu. Quello che funziona è: "db.punchdeck.findOne ({$ query: {}, $ orderby: {$ natural: -1}})"
Dave Lowerre

Non sono sicuro, perché tutti i
voti negativi

2
@dark_ruby La tua query restituisce l'errore "$ err": "Can't canonicalize query: BadValue Unsupported projection option: sort: {$ natural: -1.0}",
Roman Podlinov

20

Ho bisogno di una query con una risposta nel tempo costante

Per impostazione predefinita, gli indici in MongoDB sono B-Trees. La ricerca di un B-Tree è un'operazione O (logN), quindi anche find({_id:...})non fornirà risposte in tempo costante, O (1).

Detto questo, puoi anche ordinare in base al _idse stai usando ObjectIdper te ID. Vedi qui per i dettagli . Naturalmente, anche questo è buono solo fino all'ultimo secondo.

Puoi ricorrere alla "scrittura due volte". Scrivi una volta nella raccolta principale e scrivi di nuovo in una raccolta "ultimo aggiornamento". Senza transazioni questo non sarà perfetto, ma con un solo articolo nella collezione "ultimo aggiornamento" sarà sempre veloce.


2
Vedo molte soluzioni noSQL e MongoDB che consigliano di "scrivere due volte", principalmente per i detentori del conteggio quando la dimensione dei dati diventa molto grande. Immagino che questa sia una pratica comune?
Vinny

MongoDB non viene scaricato sul disco molto spesso e non ha transazioni, quindi le scritture diventano notevolmente più veloci. Il compromesso qui è che sei incoraggiato a denormalizzare i dati che spesso porta a più scritture. Ovviamente, se ottieni un throughput di scrittura 10x o 100x (che ho visto), 2x o 3x le scritture sono ancora un grande miglioramento.
Gates VP

13

Ancora un altro modo per ottenere l'ultimo elemento da una raccolta MongoDB (non preoccuparti degli esempi):

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

Proiezione normale

> 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." }

Proiezione ordinata (_id: ordine 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}), definisce una proiezione in ordine decrescente di tutti i documenti, in base al loro _ids.

Proiezione ordinata (_id: ordine inverso): recupero dell'ultimo (ultimo) documento da una raccolta.

> 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." }

2

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


1

La mia soluzione:

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


0

Se utilizzi gli ID oggetto Mongo generati automaticamente nel tuo documento, contiene il timestamp come primi 4 byte utilizzando l'ultimo documento inserito nella raccolta che è stato possibile trovare. Capisco che questa sia una vecchia domanda, ma se qualcuno sta ancora finendo qui a cercare un'altra alternativa.

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

La query sopra restituisce _id per l'ultimo documento inserito nella raccolta


0

Ecco come ottenere l' ultimo record da tutti i documenti MongoDB dalla raccolta "foo" (cambia foo, x, y .. ecc.)

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

puoi aggiungere o rimuovere dal gruppo

articoli della guida: https://docs.mongodb.com/manual/reference/operator/aggregation/group/#pipe._S_group

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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.