Mongodb koleksiyonundan en son rekoru alın


106

Bir koleksiyondaki en son kaydı bilmek istiyorum. Bu nasıl yapılır?

Not: Aşağıdaki komut satırı sorgularının çalıştığını biliyorum:

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

idate zaman damgasını ekledi.

Sorun, daha uzun toplama, verileri geri alma zamanı ve benim 'test' koleksiyonum gerçekten çok büyük. Sabit zamanlı yanıt veren bir sorguya ihtiyacım var.

Daha iyi bir mongodb komut satırı sorgusu varsa, bana bildirin.

Yanıtlar:


144

Bu, bir önceki cevabın bir tekrarıdır, ancak farklı mongodb versiyonları üzerinde çalışma olasılığı daha yüksektir.

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

13
db.collection.find().limit(1).sort({$natural:-1}).pretty()güzel görünmesini istiyorsanız
Anthony

Peki, bu sıralamadaki fark nedir:db.collection.find().sort({$natural:-1}).limit(1).pretty()
Aslan

@ Sonuna sınır koyarsak, çıktıyı tek bir belgeyle sınırlarken son kaydın nasıl getirildiğini ve koleksiyondaki en iyi belge olması gerektiğini belirtir.
kailash yogeshwar

Güzel cevap. Şunu denedim: db.collection ("koleksiyonun adı"). Find ({}, {limit: 1}). Sort ({$ doğal: -1})
Abdul Alim Shakir

Herkes AWS DocDB kullanarak: Query failed with error code 303 and error message 'option $natural is not supported' on server docdb. Umarım bu özellik yakında gelir.
Marc

35

Bu size son bir belge verecek collection

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

$natural:-1 kayıtların eklendiği sıranın tersi anlamına gelir.

Düzenleme : Tüm olumsuz oy verenler için yukarıda Mongoose sözdizimi verilmiştir, mongo CLI sözdizimi şöyledir:db.collectionName.find({}).sort({$natural:-1}).limit(1)


7
Sözdiziminiz yanlış görünüyor. Senin sahip olduğun gibi çalışmasını sağlayamıyorum. İşe yarayan şey: 'db.punchdeck.findOne ({$ query: {}, $ orderby: {$ natural: -1}})'
Dave Lowerre

emin değilim, neden tüm olumsuz oylar - bu kod benim için mükemmel çalışıyor ve hızlı
dark_ruby

2
@dark_ruby Sorgunuz "$ err" hatası veriyor: "Sorgu standartlaştırılamıyor: BadValue Desteklenmeyen projeksiyon seçeneği: sıralama: {$ doğal: -1.0}",
Roman Podlinov

19

Sabit zamanlı yanıt veren bir sorguya ihtiyacım var

Varsayılan olarak, MongoDB'deki dizinler B-Trees'tir. Bir B-Ağacı araması bir O (logN) işlemidir, dolayısıyla find({_id:...})sabit zaman, O (1) yanıtları bile sağlamaz.

Bununla birlikte, kimlikleriniz için _idkullanıyorsanız , buna göre de sıralayabilirsiniz ObjectId. Ayrıntılar için buraya bakın . Tabii ki, bu bile sadece son saniyeye kadar iyidir.

"İki kez yazmaya" başvurabilirsiniz. Ana koleksiyona bir kez yazın ve "son güncellenen" bir koleksiyona tekrar yazın. İşlemler olmadan bu mükemmel olmayacak, ancak "son güncellenen" koleksiyondaki yalnızca bir öğe ile her zaman hızlı olacaktır.


2
"İki kez yazmayı" savunan çok sayıda noSQL ve MongoDB çözümü görüyorum, çoğunlukla veri boyutu çok büyük olduğunda sayaç sahipleri için. Bunun yaygın bir uygulama olduğunu tahmin ediyorum?
Vinny

1
MongoDB diske çok sık boşaltmaz ve hiçbir işlemi yoktur, bu nedenle yazma işlemleri önemli ölçüde daha hızlı hale gelir. Buradaki değiş tokuş, genellikle birden çok yazmaya yol açan verileri normalleştirmeye teşvik edilmenizdir. Tabii ki, 10x veya 100x yazma performansı elde ederseniz (ki bunu gördüm), 2x veya 3x yazma hala büyük bir gelişmedir.
Gates VP

15

Bir MongoDB Koleksiyonundan son öğeyi almanın başka bir yolu (örneklere aldırmayın):

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

Normal Projeksiyon

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

Sıralanmış Projeksiyon (_id: ters sıralama)

> 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}), belgelerine bağlı olarak tüm belgelerin azalan sırasına göre bir projeksiyonu tanımlar _id.

Sıralanmış Projeksiyon (_id: ters sıra): bir koleksiyondan en son (son) belgeyi alma.

> 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

"Foo" koleksiyonundaki tüm MongoDB belgelerinden son kaydı bu şekilde alabilirsiniz . (Foo, x, y .. vb. Değiştirin)

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

gruba ekleyebilir veya gruptan kaldırabilirsiniz

yardım makaleleri: https://docs.mongodb.com/manual/reference/operator/aggregation/group/#pipe._S_group

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


0

Belgenizde otomatik olarak oluşturulan Mongo Nesne Kimlikleri kullanıyorsanız, koleksiyona eklenen en son belgenin bulunabileceği ilk 4 bayt olarak içinde zaman damgası içerir. Bunun eski bir soru olduğunu anlıyorum, ama eğer birisi hala burada bir alternatif daha arıyor ise.

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

Yukarıdaki sorgu , koleksiyona eklenen en son doküman için _id verir

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.