2017-03-07 29 views
6

在MongoDB的約tailable光標文件它規定了以下內容:查詢的MongoDB的索引字段VS Tailable光標

如果查詢是一個索引字段,不要使用tailable光標,而是使用常規的光標。跟蹤查詢返回的索引字段的最後一個值。要檢索新添加的文檔,請使用查詢條件中索引字段的最後一個值再次查詢集合

我正在設置查詢以查找特定時間點之後的所有文檔,然後在插入文檔時不斷返回文檔。我想這樣做的最簡單方法是查詢_id(假設我們使用ObjectIds,我們是)任何$ gt的時候我想要的。

由於_id默認編入索引,它不斷地輪詢MongoDb與我得到的最後_id並繼續詢問事情$ gt嗎?我意識到這隻會在1秒左右的精度左右,因爲ObjectIds只存儲秒以來的時間,但我可以忍受,所以我認爲我會每秒至少查詢一次。

我想我只是感到驚訝,文檔建議的方式查詢(大概,不斷在我的情況下)與保持可打開的光標打開:我會認爲推會比拉更便宜?

+0

_「...然後在插入文檔時保持返回」_「。你在用新插入的文件做什麼?什麼在消耗他們? –

回答

1

在這裏有一個很大的警告,我認爲你可能忽略了。 Tailable遊標只有工作capped collections。使用加蓋集合可能不是一個通用的解決方案,它需要仔細規劃,以確保您適當調整加蓋集合的大小,以適應您的數據大小和增長。

0

如果用tailable光標去,還有,我能想到的幾個問題:

  1. 你必須接受集合中的每一個消息之前,我們得到的「結束」
  2. 你有如果耗盡遊標(及其await_data延遲),則返回到開始位置。所以,如果應用程序重新啓動,數據庫重新啓動等你沒有任何選擇,但從一開始迭代。

除了上面的內容,還有一些使用可放大光標的警告,因爲它們只能用於加蓋的集合。

  1. 連接數量的可擴展性限制。每個客戶端連接都會在mongod服務器(或mongos)中添加一個連接線程。
  2. 封頂集合具有固定的最大尺寸。文件不能超過這個尺寸。
  3. 不能分割加蓋集合
  4. 對加蓋集合中的文檔進行的任何更新都不得導致文檔增長。 (即不是所有$set操作會工作,並沒有$push$pushAll會)
  5. 您可以由封閉的集合
  6. 沒有明確.remove()文件你沒有哪個文件會從集合中刪除任何控制。它會像一個循環隊列。

是多麼糟糕它與過去的_id我和 不斷地問東西$ GT它不斷地輪詢MongoDB的?

IMO,輪詢會引入延遲和不必要的忙碌等待,即使沒有更新但您有很多控制權。

表現明智,只要您使用索引字段進行查詢,就不應該存在問題。

0

它聽起來像你想要的是被通知在數據庫中的新/更新/刪除的對象。這對於沒有一點小技巧的MongoB來說是不可能的。我猜你已經閱讀過使用可放大遊標來閱讀oplog,而投票總是絕對不得已而爲之。我從來沒有嘗試過這些,因爲它們似乎有一點限制(不能在共享數據庫環境中使用它們),並且不可靠 - 更不用說難以設置(需要複製集),並且在未來的任何時候都容易發生變化而不會發出警告。例如,曾經流行的圖書館不再維持更好的選擇)。

DB「突變事件」實現了一些數據庫:Postgres實現觸發器,而RethinkDB實際上向您推送更改。如果你可以切換到RethinkDB之類的東西 - 那會很理想。

如果不是,我最好的建議是把你的數據庫的服務層放在你的數據庫前面,所有的流量必須通過它。客戶端應用程序可以通過套接字連接到這些服務(使用socket.io這幾乎是微不足道的 - 幾乎在每種語言中都可以實現)。任何時候你的服務層處理一個更新,插入刪除,你可以發送這些事件給任何當前連接的人。

約束這種方法

  • 所有的數據庫通信應該通過服務層。

注意事項這種方法

  • 如果有什麼直接更新數據庫,你不會立即看到這些變化。你必須再次查詢數據庫。不是世界末日。

優點,使用這種方法

  • 它的方式更好,更高性能,更實時輪詢相比。
  • 你有一個服務層,它可以做更多的業務的東西與你的數據,如發射事件時數據的變化,驗證數據,發送電子郵件,記錄,更新其他數據源等)
  • 這是一個範式適用於任何語言,任何分貝。
  • 那裏有輕量級的框架,已經實現了這個架構。 FeathersJS是我的最愛。你應該真的檢查出來。如果你不能使用NodeJS,至少應該從羽毛服務的工作中得到一些提示。
0

提供的答案已經很好,並且重點突出。然而,當我第一次看到你的問題和問題時,也許我不完全明白你到底想要做什麼,這聽起來像這個問題/解決方案是建立在Redis。將緩存設置爲獲取/接收信息,您可以訪問它,並在需要時從緩存中刪除信息,這相當簡單。

此外,對數據庫的讀取/寫入操作以及其他操作的數量仍然保持健全,因爲您將輪詢緩存。

再一次,也許我沒有正確理解問題,但正確設置Redis並使用它似乎是在這種情況下去的方式。聽起來像它是爲緩存答案。