2017-07-19 32 views
0

讓我試着首先解釋我的問題,然後解決我正在實施。我有一系列「事件」,可以與特定用戶共享。我也有一批「用戶」。任何用戶都可以與任何數量的其他用戶共享一個事件。當一個事件與用戶共享時,它會在該用戶的網站主頁中看到(假設它是按創建日期排序的,以便簡化)。用mongodb分片。最好的方式來寫我的查詢

我想使用分片來平衡寫入和讀取,並且能夠根據需要進行水平縮放。在我想到分片之前,我有一個事件集合,裏面有一個userIds數組。那些用戶標識符是可以看到事件的那些用戶標識符。我的查詢就是每個事件,其中登錄用戶包含在該數組中,按創建日期排序,限制爲我的頁面大小。

要在這種情況下實現分片,明顯的選擇是以某種方式將userId作爲分片鍵,因爲每個由我的查詢返回的事件都具有該嵌入數組中的userId。但是,我的userId包含在一個數組中,所以這是行不通的。然後,我雖然有一個新的集合,具有以下字段:

  • 用戶id:物件(哈希片鍵,以避免單調)
  • 事件ID:OBJECTID
  • creationDate:日期

這樣,我可以通過userId運行我的查詢,並只讓它進入相應的分片。我當然對這個解決方案的問題是,我現在有eventIds而不是事件,這是一個大大的文檔,所以我不希望冗餘地將它作爲該集合中的嵌入文檔(記住許多用戶可以共享事件)。

爲了解決這個問題,我認爲正確的解決方案是將eventId作爲事件集合的分片鍵(再次散列以避免單調)。然後我可以通過這些ID查詢事件集合。

這就產生了兩個問題:

  1. 這是思考這個特定問題的正確方法。這是一個好的解決方案嗎?
  2. 因爲我現在有幾個eventIds,我們只說五個,並且它們中的每一個都可以位於不同的分片中,這更好的表現形式:有一個查詢查找五個id,或者有五個不同的查詢尋找每一個單一的ID?

回答

0
  1. 是的,這是正確的方法和解決方案是好的。用戶使用userId分割並使用eventId分割事件。
  2. 後一個。五個不同的查詢搜索單身份證,因爲然後查詢去一個分片。如果你有單個查詢同時看到五個ID($ in:[]),它可能會分散到多個分片。
+0

關於第二點。你說有一個($ in:[])會使它分散,這是絕對正確的。但是,執行五個不同的查詢也會「分散」,因爲每個查詢都可能會轉到不同的分片。我的意思是,在這兩種情況下受影響的碎片都是完全相同的,不是嗎? – manugarciac

+0

不完全......但差異會很小。只有一個ID發送查詢到碎片,碎片會很快從索引中找到它。將ID列表發送給每個分片和分片需要多次查看該索引,以查找哪些ID在「他的」索引中。多個單一ID查詢是並行的,一個多個ID查詢不是。 – JJussi

+0

我明白了。具有不同的查詢實際上使得我的應用程序邏輯更加容易,所以如果它更好,甚至相同,那將會很好。我不應該擔心做多個查詢會產生一個開銷嗎? – manugarciac

相關問題