2012-06-06 14 views
53

Desidero conoscere il record più recente in una raccolta. Come farlo?Ottieni l'ultimo record dalla collezione mongodb

Nota: So che la seguente riga di comando interroga opere:

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 momento di recuperare i dati e la mia raccolta 'test' è davvero enorme. Ho bisogno di una query con risposta temporale costante.

Se è presente una query della riga di comando mongodb migliore, fatemi sapere.

risposta

17

ho bisogno di una query con tempo di risposta costante

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

Ciò detto, è anche possibile ordinare dal _id se si utilizza ObjectId per gli ID. See here for details. Naturalmente, anche questo è solo buono fino all'ultimo secondo.

È possibile ricorrere a "scrivere due volte". Scrivi una volta alla raccolta principale e scrivi di nuovo in una raccolta "last updated". Senza transazioni questo non sarà perfetto, ma con un solo articolo nella collezione "last updated" sarà sempre veloce.

+2

Vedo un sacco di soluzioni NoSQL e MongoDB sostenendo "scrivere due volte", per lo più per i titolari di conteggio quando la dimensione dei dati diventa molto grande. Immagino che questa sia una pratica comune? – Vinny

+0

MongoDB non esegue il flush su disco molto spesso e non ha transazioni, quindi le scritture diventano significativamente più veloci. Il compromesso qui è che sei incoraggiato a de-normalizzare i dati che spesso portano a più di una scrittura. Ovviamente, se ottieni un throughput di scrittura 10x o 100x (che ho visto), quindi 2x o 3x le scritture sono ancora un grande miglioramento. –

14

Questo vi darà un ultimo documento per un collection

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

$natural:-1 significa ordine opposto di quello che i record vengono inseriti in

Edit:. Per tutti i downvoters, di cui sopra è un Sintassi di Mongoose, La sintassi di mongo CLI è: db.collectionName.find({}).sort({$natural:-1}).limit(1)

+6

La sintassi sembra essere sbagliata. Non riesco a farlo funzionare come tu hai. Che cosa funziona è: 'db.punchdeck.findOne ({$ query: {}, $ orderby: {$ natural: -1}}) ' –

+0

non sono sicuro, perché tutti i downvotes - questo codice funziona perfettamente per me, ed è veloce –

+1

@dark_ruby Si interroga l'errore restituito "$ err ":" Can not canonicalize query: BadValue Opzione di proiezione non supportata: sort: {$ natural: -1.0} ", –

78

Questo è un rehash della risposta precedente ma è più probabile che w ork su diverse versioni di mongodb.

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

' db.collection.find(). limit (1) .sort ({$ natural: -1}) .pretty() 'se vuoi che sia bello – Antoine

+0

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

+0

@Digita quale impatto sulle prestazioni avrà se poniamo un limite alla fine anche come viene recuperato l'ultimo record quando si limita l'output a un solo documento e deve essere il documento principale nella raccolta. –

-1

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

0

mia soluzione:

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

Problemi correlati