Article {
"_id" : "A",
"title" : "Hello World",
"user_id" : 12345,
"text" : 'My test article',
"comments" : [
{ 'text' : 'blah', 'user_id' : 654321, 'votes' : [987654]},
{ 'text' : 'foo', 'user_id' : 987654, 'votes' : [12345, 654321] },
...
]
}
這裏的基本前提是,我已經嵌套在Comments
的Article
內。 Votes
僅適用於Comment
,因此它們已被存儲爲每個Comment
的陣列。在這種情況下,我剛剛存儲了user_id。如果你想存儲更多的信息(TIME_CREATED等),那麼你可以投票對象的數組:
... 'votes' : [ { user_id : 987654, ts : 78946513 } ] ...
如何執行你的查詢效率:
- 獲得A條評論每評論
db.articles.find({ _id : 'A' })
這得到第一個和#票一切都有一個查詢。您可能必須執行一些客戶端邏輯來對每條評論的投票數進行計數,但這非常簡單。
- 得到用戶B所有評論所有文章
db.articles.ensureIndex({ "comments.user_id" : 1 })
db.articles.find({ "comments.user_id" : 987654 }) // returns all document fields
該指數將允許有效地搜索文檔中的註釋。
目前沒有辦法只從子數組中提取匹配。該查詢實際上將返回所有包含該用戶評論的文章。如果這可能是太多的數據,你可以做一些修整。
db.articles.find({ "comments.user_id" : 987654 }, { "title" : 1, "comments.user_id" : 1 })
- 讓所有評論用戶B投票贊成
db.articles.ensureIndex({ "comments.votes" : 1 })
db.articles.find({ "comments.votes" : 987654 })
同樣,這將返回所有的文章,不只是評論。
這裏有一個折衷。返回文章可能看起來像我們正在帶回太多的數據。但是,當您進行查詢#3時,您計劃向用戶展示什麼?
獲取的評論「我已投票評論」沒有評論本身並不是非常有用。如果沒有文章本身(或者至少只是標題),評論當然不是很有用。
大多數情況下,查詢#3分配從Votes
到Comments
到Articles
的連接。如果是這樣的話,那麼爲什麼不把條款帶回來呢?
那麼16MB /文件的限制呢? – 2014-01-29 00:43:13
如果您擔心有一篇博文超過16MB(_that是很多text_),那麼您需要製作一個不同的模式設計。許多博客實際上將其作爲單獨的查詢來源,因此他們實際上不會同時訪問這兩個作品。如果這是你的擔心,那麼你選擇一個不同的模式。 – 2014-01-29 02:49:24
我需要一個類似的博客設計,我需要從所有文章中按照日期排序來評論評論。現在這個結果也應該分頁。我是否應該堅持這種架構或將評論部分放到另一個集合中? – 2014-07-14 17:11:56