Holen Sie sich die neueste Platte aus der Mongodb-Sammlung

99

Ich möchte den neuesten Datensatz in einer Sammlung kennen. Wie geht das?

Hinweis: Ich weiß, dass die folgenden Befehlszeilenabfragen funktionieren:

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

wo idate den Zeitstempel hinzugefügt hat.

Das Problem ist, dass die Sammlung länger ist, um die Daten zurückzugewinnen, und meine 'Test'-Sammlung ist wirklich sehr, sehr groß. Ich benötige eine Abfrage mit konstanter Zeitantwort.

Wenn es eine bessere Mongodb-Befehlszeilenabfrage gibt, lassen Sie es mich wissen.

inkriti
quelle

Antworten:

138

Dies ist eine Wiederholung der vorherigen Antwort, aber es ist wahrscheinlicher, dass sie auf verschiedenen Mongodb-Versionen funktioniert.

db.collection.find().limit(1).sort({$natural:-1})
Ziffern
quelle
10
db.collection.find().limit(1).sort({$natural:-1}).pretty()wenn du willst, dass es schön aussieht
Anthony
Also, was ist der Unterschied bei dieser Bestellung:db.collection.find().sort({$natural:-1}).limit(1).pretty()
Leo
@Digits welche Auswirkungen auf die Leistung hat es, wenn wir am Ende ein Limit setzen und auch, wie der letzte Datensatz abgerufen wird, wenn Sie die Ausgabe auf nur ein Dokument beschränken und es das oberste Dokument in der Sammlung sein muss.
Kailash Yogeshwar
Gute Antwort. Ich habe es so versucht: db.collection ("Name der Sammlung"). Find ({}, {limit: 1}). Sort ({$ natural: -1})
Abdul Alim Shakir
Für alle, die AWS DocDB verwenden : Query failed with error code 303 and error message 'option $natural is not supported' on server docdb. Hoffentlich kommt diese Funktion bald.
Marc
33

Dies gibt Ihnen ein letztes Dokument für a collection

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

$natural:-1 bedeutet die entgegengesetzte Reihenfolge wie die, in die Datensätze eingefügt werden.

Bearbeiten : Für alle Downvoters ist oben eine Mongoose-Syntax, die Mongo-CLI-Syntax lautet:db.collectionName.find({}).sort({$natural:-1}).limit(1)

dark_ruby
quelle
7
Ihre Syntax scheint falsch zu sein. Ich kann es nicht zum Laufen bringen, wie Sie es haben. Was funktioniert, ist: 'db.punchdeck.findOne ({$ query: {}, $ orderby: {$ natural: -1}})'
Dave Lowerre
Ich bin mir nicht sicher, warum all die Downvotes - dieser Code funktioniert perfekt für mich und ist schnell
dark_ruby
2
@dark_ruby Ihre Abfrage gibt den Fehler "$ err" zurück: "Abfrage kann nicht kanonisiert werden: BadValue Nicht unterstützte Projektionsoption: sort: {$ natural: -1.0}",
Roman Podlinov
20

Ich benötige eine Abfrage mit konstanter Zeitantwort

Standardmäßig sind die Indizes in MongoDB B-Bäume. Das Durchsuchen eines B-Baums ist eine O-Operation (logN), sodass selbst find({_id:...})keine O (1) -Antworten mit konstanter Zeit bereitgestellt werden .

Sie können jedoch auch nach den IDs sortieren, die _idSie ObjectIdfür Ihre IDs verwenden. Siehe hier für Details . Natürlich ist auch das nur bis zur letzten Sekunde gut.

Sie können auf "zweimal schreiben" zurückgreifen. Schreiben Sie einmal in die Hauptsammlung und erneut in eine "zuletzt aktualisierte" Sammlung. Ohne Transaktionen ist dies nicht perfekt, aber mit nur einem Artikel in der "zuletzt aktualisierten" Sammlung ist es immer schnell.

Gates VP
quelle
2
Ich sehe viele noSQL- und MongoDB-Lösungen, die "zweimal schreiben" befürworten, hauptsächlich für Zählhalter, wenn die Datenmenge sehr groß wird. Ich vermute, das ist gängige Praxis?
Vinny
MongoDB wird nicht sehr oft auf die Festplatte gespült und es gibt keine Transaktionen, sodass Schreibvorgänge erheblich schneller werden. Der Nachteil hierbei ist, dass Sie aufgefordert werden, Daten zu de-normalisieren, was häufig zu mehreren Schreibvorgängen führt. Wenn Sie einen 10-fachen oder 100-fachen Schreibdurchsatz erhalten (was ich gesehen habe), ist das 2-fache oder 3-fache des Schreibvorgangs natürlich immer noch eine große Verbesserung.
Gates VP
13

Noch eine andere Möglichkeit, das letzte Element aus einer MongoDB-Sammlung zu erhalten (die Beispiele machen nichts aus):

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

Normale Projektion

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

Sortierte Projektion (_id: umgekehrte Reihenfolge)

> 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}), definiert eine Projektion in absteigender Reihenfolge aller Dokumente, basierend auf ihren _ids.

Sortierte Projektion (_id: umgekehrte Reihenfolge): Abrufen des neuesten (letzten) Dokuments aus einer Sammlung.

> 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
quelle
2

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

Sam
quelle
1

Meine Lösung :

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

Abdul Alim Shakir
quelle
0

Wenn Sie in Ihrem Dokument automatisch generierte Mongo-Objekt-IDs verwenden, enthält dieser einen Zeitstempel als erste 4 Byte, anhand dessen das zuletzt in die Sammlung eingefügte Dokument ermittelt werden konnte. Ich verstehe, dass dies eine alte Frage ist, aber wenn noch jemand hier landet, der nach einer weiteren Alternative sucht.

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

Die obige Abfrage würde die _id für das letzte in die Sammlung eingefügte Dokument angeben

Chan15
quelle
0

So erhalten Sie den letzten Datensatz aus allen MongoDB-Dokumenten aus der "foo" -Sammlung (ändern Sie foo, x, y .. usw.)

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

Sie können der Gruppe hinzufügen oder daraus entfernen

Hilfeartikel: https://docs.mongodb.com/manual/reference/operator/aggregation/group/#pipe._S_group

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

ssymbiotik
quelle