Zdobądź najnowszą płytę z kolekcji Mongodb

99

Chcę poznać najnowszy rekord w kolekcji. Jak to zrobić?

Uwaga: wiem, że działają następujące zapytania w wierszu poleceń:

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

gdzie idate ma dodany znacznik czasu.

Problem polega na tym, że dłużej zbieranie danych to czas na odzyskanie danych, a moja kolekcja „testowa” jest naprawdę ogromna. Potrzebuję zapytania ze stałą odpowiedzią czasową.

Jeśli jest jakieś lepsze zapytanie wiersza poleceń mongodb, daj mi znać.

inkriti
źródło

Odpowiedzi:

138

To jest powtórzenie poprzedniej odpowiedzi, ale jest bardziej prawdopodobne, że będzie działać na różnych wersjach mongodb.

db.collection.find().limit(1).sort({$natural:-1})
Cyfry
źródło
10
db.collection.find().limit(1).sort({$natural:-1}).pretty()jeśli chcesz, żeby wyglądało ładnie
Anthony
Jaka jest więc różnica w tym zamówieniu:db.collection.find().sort({$natural:-1}).limit(1).pretty()
Lew
@Digits, jaki wpływ na wydajność będzie miało, jeśli na końcu umieścimy limit, a także sposób pobierania ostatniego rekordu, gdy ograniczasz wynik do jednego dokumentu i musi to być najwyższy dokument w kolekcji.
kailash yogeshwar
Niezła odpowiedź. Próbowałem w ten sposób: db.collection ("nazwa kolekcji"). Find ({}, {limit: 1}). Sort ({$ natural: -1})
Abdul Alim Shakir
Dla każdego, używając AWS DocDB: Query failed with error code 303 and error message 'option $natural is not supported' on server docdb. Mam nadzieję, że ta funkcja pojawi się wkrótce.
Marc
34

To da ci ostatni dokument dla collection

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

$natural:-1 oznacza kolejność odwrotną do tej, do której wstawiane są rekordy.

Edycja : dla wszystkich downvoters powyżej jest składnia Mongoose, składnia mongo CLI to:db.collectionName.find({}).sort({$natural:-1}).limit(1)

dark_ruby
źródło
7
Twoja składnia wydaje się być błędna. Nie mogę zmusić go do pracy tak, jak go masz. Co działa to: „db.punchdeck.findOne ({$ query: {}, $ orderby: {$ natural: -1}})”
Dave Lowerre,
nie jestem pewien, po co te wszystkie głosy w dół - ten kod u mnie działa idealnie i jest szybki
dark_ruby
2
@dark_ruby You query zwraca błąd "$ err": "Can't canonicalize query: BadValue Unsupported projection option: sort: {$ natural: -1.0}",
Roman Podlinov
20

Potrzebuję zapytania ze stałą odpowiedzią czasową

Domyślnie indeksy w MongoDB to B-drzewa. Przeszukiwanie B-Tree jest operacją O (logN), więc nawet find({_id:...})nie zapewni stałego czasu, odpowiedzi O (1).

To powiedziawszy, możesz również sortować według, _idjeśli używasz ObjectIddla siebie identyfikatorów. Zobacz tutaj, aby uzyskać szczegółowe informacje . Oczywiście nawet to jest dobre tylko do ostatniej sekundy.

Możesz uciec się do „pisania dwa razy”. Napisz raz do kolekcji głównej i napisz ponownie do kolekcji „ostatnio zaktualizowanej”. Bez transakcji nie będzie to idealne, ale mając tylko jedną pozycję w kolekcji „ostatnio zaktualizowanej”, zawsze będzie to szybkie.

Gates VP
źródło
2
Widzę wiele rozwiązań noSQL i MongoDB zalecających „dwukrotne pisanie”, głównie dla posiadaczy liczników, gdy rozmiar danych staje się bardzo duży. Zgaduję, że to powszechna praktyka?
Vinny
MongoDB nie ładuje się zbyt często na dysk i nie zawiera transakcji, więc zapisy stają się znacznie szybsze. Kompromis polega na tym, że zachęca się do cofnięcia normalizacji danych, co często prowadzi do wielokrotnych zapisów. Oczywiście, jeśli uzyskasz 10x lub 100x przepustowość zapisu (co widziałem), to 2x lub 3x zapisy to nadal duża poprawa.
Gates VP,
13

Jeszcze inny sposób na uzyskanie ostatniego elementu z kolekcji MongoDB (nie przejmuj się przykładami):

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

Projekcja normalna

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

Rzutowanie sortowane (_id: odwrotna kolejność)

> 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}), definiuje odwzorowanie w porządku malejącym wszystkich dokumentów na podstawie ich plików _id s.

Sorted Projection (_id: reverse order): pobieranie najnowszego (ostatniego) dokumentu z kolekcji.

> 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
źródło
2

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

Sam
źródło
1

Moje rozwiązanie:

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

Abdul Alim Shakir
źródło
0

Jeśli korzystasz z automatycznie generowanych identyfikatorów obiektów Mongo w swoim dokumencie, zawiera on znacznik czasu jako pierwsze 4 bajty, na podstawie którego można znaleźć najnowszy dokument wstawiony do kolekcji. Rozumiem, że to stare pytanie, ale jeśli ktoś jeszcze tu ląduje, szuka jeszcze jednej alternatywy.

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

Powyższe zapytanie dałoby _id dla najnowszego dokumentu wstawionego do kolekcji

Chan15
źródło
0

W ten sposób można pobrać ostatni rekord ze wszystkich dokumentów MongoDB z kolekcji „foo”. (Zmień foo, x, y .. itd.)

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

możesz dodawać lub usuwać z grupy

artykuły pomocy: https://docs.mongodb.com/manual/reference/operator/aggregation/group/#pipe._S_group

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

ssymbiotik
źródło