2012-09-08 58 views
1

我已經有了一個場景,其中的文檔在彈性搜索中被編入索引,並且我需要檢索mongo中的匹配文檔以及按照時間戳排序的前面和後面的文檔。這個想法是與原始文檔一起檢索文檔的上下文。基於_id獲取順序文檔

如果我使用順序的_id,我現在能夠成功完成此操作。作爲一個例子,使用下面的數據:

[ 
    {_id: 1, value: 'Example One' }, 
    {_id: 2, value: 'Example Two' }, 
    {_id: 3, value: 'Example Three' }, 
    {_id: 4, value: 'Example Four' }, 
    {_id: 5, value: 'Example Five' }, 
    {_id: 6, value: 'Example Six' }, 
    ... 
] 

如果我搜索在ES「四」,我回來的4文檔_id,因爲它是連續的,我可以創造一個蒙戈查詢拉ID之間的範圍 - 2和id + 2,在這種情況下是2 - 6.只要我不刪除文檔,這種方式效果很好。當我刪除一個文檔時,我將不得不重新編制整個系列的索引以消除差距。我正在尋找一種達到相同結果的方式,同時也能夠刪除文件而無需更新所有文件。

我很樂意使用其他技術來實現這一點,我不一定與mongodb綁定。

回答

0

這個問題與MongoDB無關,與使用不同的數據庫(例如RDBMS)沒有什麼不同。您將不得不循環查找小於/大於當前ID的文檔ID,並查找前兩個匹配項。是的,這意味着您需要執行多個查詢。唯一的其他選擇是在MongoDB之上實現鏈接列表,您可以在其中存儲指向左右鄰居節點的指針。是的,在刪除的情況下,您需要調整指針(基本數據結構算法....)。缺點是:您將需要多個操作才能執行更改。由於MongoDB不是事務處理,你可能遇到不一致的前一個/下一個指針....這就是爲什麼MongoDB完全在這裏吸引。

+0

使用RDBMS時還有其他方法可以解決這個問題。例如,使用SQL Server,我可以使用帶有ROW_NUMBER的CTE。我可能能夠使用地圖縮小功能獲得我正在尋找的內容。我得看看那個。 –

1

我可以使用類似以下的預期效果:

collection.find({_id: { $gte: matchedId } }).limit(3); 
collection.find({_id: { $lt: matchedId } }).sort({$natural: -1}).limit(2); 

不太一樣好使用一個明確的範圍,但沒有必要重新計算文件刪除任何東西。

是的,我知道limitations of natural order,這對我的特殊用例不是問題。

+0

關於自然順序的一個注意事項:除非您有上限的集合,否則隨着時間的推移自然順序將與您期望的「上一個/下一個」文檔不匹配。特別是文檔的刪除和移動會在可以插入或移動文檔的可用數據空間中產生差距。如果您期待某個訂單(例如廣告訂單),則應該使用顯式索引排序()。在你的例子中,你想要在'_id'字段上排序。 – Stennie