簡體   English   中英

使用findOne()MongoDB從集合中檢索第一個文檔

[英]Retrieve first document from collection using findOne() MongoDB

我正在創建一個Java程序來處理MongoDB的Collection作為隊列。 因此,當我出隊時,我想要首先插入的文檔。

為此,我有一個名為created的字段,它表示文檔創建的時間戳,我的最初想法是使用聚合$ min來使用created字段查找最小的文檔。

但是我想到了為什么不使用不帶任何參數的findOne()。 它將始終返回集合中的第一個文檔。

所以我的問題是我應該這樣做嗎? 使用findOne()並從Mongo Queue中取出第一條記錄是否是一個好方法? 如果這樣做的話,缺點是什么?

PS:創建了Mongo Queue程序以根據“先到先得”的原則服務設備的請求。 但是由於執行該請求會花費一些時間,並且設備在處理另一個請求時無法接受另一個請求。 因此,為防止一個請求丟失,我使用隊列來逐個處理請求。

有趣的是這里有多少人發表了錯誤的評論,但您說對了,因為帶有空白查詢或.findOne({})的原始.findOne() .findOne({})將返回集合中的第一個文檔,即“具有最低_id值的文檔”。

理想情況下,對於隊列處理系統,您希望與此同時刪除文檔。 為此,Java API支持.findAndRemove()方法:

    DBCollection data = mongoOperation.getCollection("data");
    DBObject removed = data.findAndRemove(new DBObject());

這樣,它將按所述返回集合中的第一個文檔,並從集合中“刪除”它,以便其他操作無法找到它。

您可以調用.findAndModify()並自己交替設置所有選項,但是如果您所需要的只是“最早的文檔優先”,這是_id保證的,那么這就是您想要的。

findOne自然順序返回元素。 這不一定與插入順序相同。 它是文檔在磁盤中出現的順序。 看起來好像是按插入順序對其進行了檢索,但是刪除和插入后,您將開始看到文檔亂序顯示。

確保元素始終按插入順序出現的一種方法是使用上限集合 如果您的應用程序不受其限制的影響,則這可能是獲得帶上限收集的隊列的最簡單方法。

上限集合也可以與可尾光標一起使用,以便從隊列中檢索項目的邏輯可以繼續等待項目(如果沒有可處理的項目)。

更新:如果不能使用上限收集,則如果結果為ObjectId,則必須按_id對結果進行排序,或者將基於時間戳的字段保留在集合中,並按該字段對結果進行排序。

FindOne使用幕后內部MongoDB內部bTree中的$natural順序返回。

默認情況下,該函數不按_id排序,也不會選擇最低的_id

如果您發現它定期返回最低的_id ,那是由於文檔位於$natural索引內。

獲取集合的第一個文檔和排序集的第一個文檔是完全不同的兩件事。

如果您想使用findAndModify來獲取文檔,我個人建議使用樂觀鎖,那么您需要使用:

findAndModify({
    sort: {_id: -1},
    remove: true
})

我之所以不推薦這種方法,是因為該進程崩潰或服務器在分布式工作集中失敗,然后您丟失了該數據點。 相反,您需要一個臨時(樂觀類型)鎖,如果未正確處理它,可以將其釋放。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM