2016-10-29 22 views
0

我有一個應用程序(內置流星),爲最終用戶提供了一些臨時報告功能。我已經通過使用聚合管道爲給定查詢生成結果來構建該功能。這使得它非常快速,我使用$out將結果直接推送到結果表中。是否動態創建和刪除MongoDB中的集合以創建可伸縮性問題?

結果表包括一個queryID,其中,客戶端用來找出哪些是正確的結果。

不幸的是,正如您可能知道的(並且我發現的),一旦您有多個用戶同時運行報表,因爲$out在推送新查詢之前刪除了整個結果表。

我看到三個可能的解決方法:

  1. 運行聚集,但手動結果推到結果集
  2. $out結果到一個臨時集合(動態命名,以避免衝突),然後手動複製從那裏的結果到結果收集,立即放棄臨時的一個。當我認爲我可以使用copyTo()時,這是有道理的,但在Meteor中這似乎不可能,所以我認爲這種選擇在這種情況下相對於#1沒有多大意義。
  3. $out結果到一個臨時集合(動態命名,以避免衝突),並讓客戶端直接從那裏拉其結果。然後,我會在24小時後定期刪除額外的收藏(就像我今天在主要收藏中的具體查詢結果一樣)。

#3將是迄今爲止最快的 - 手動複製行花費的時間會縮短查詢運行所花費的時間。但我很擔心創建和刪除這麼多集合的影響。

我們不是在談論數百萬用戶在這裏,但如果每天500名用戶平均分別運行10-20報告,有可能是數據庫中的任一個時刻的額外5-10K集合。這似乎很多。也許我可以更聰明地以某種方式清理它們,儘管我不能立即刪除它們,因爲用戶可能希望使用不同的報告打開多個選項卡。即使如此,我們仍有可能談論數百到數千個藏品。

這會是一個問題嗎?

是我應該考慮,而不是有其他的辦法?

其他建議?

謝謝!

回答

1

刪除MongoDB中的集合是非常有效的操作,反正不是刪除一些文件,更有效一個更大的集合。 集合的最大數量非常高,僅受限於MMAPv1中的名稱空間namespace,而wiretiger引擎中沒有硬性限制。 所以我希望你的解決方案#3。 一些改進/替代方案,你能想到:

  1. 考慮在分離數據庫中創建集合(每天說的),那麼你可以滴在一次操作整個數據庫而不必刪除個人收藏。
  2. 對結果集使用端點,兌現結果,然後放下$ out集合。讓緩存處理用戶需求,並且只在緩存過期或其他情況下重新運行聚合。
0

這種活動是在關係數據庫如MySQL或pgsql的很輕鬆地完成。出於報告的目的,您可能會考慮將數據同步到單獨的關係數據庫。

有一個包https://github.com/perak/mysql-shadow號稱提供同步。我玩過它,並沒有完美的工作,雖然做單向同步更有可能成功。

另一種選擇是使用Graphql了可與阿波羅做一個蒙戈/ MySQL的混合數據庫堆棧http://www.apollodata.com/