2015-09-20 54 views
0

假設我有一個有成千上萬用戶的服務,並且我想發佈他們可以查看的新聞提醒。一旦他們看到一個,它被標記爲看到(顯然,只爲那個用戶)。MongoDB - 如何處理閱讀新聞提醒的用戶

我想我知道這個答案,但是在新聞項目上存儲一個已經看到它的用戶列表是否更好?或者,最好在用戶文檔上存儲他們看到的所有新聞項目的列表?

我假設後者更好,主要是因爲如果我有20,000用戶,這意味着如果他們都看到了特定的新聞提醒,那麼我有一個存儲在該新聞提醒文檔中的20,000個ID的數組,這可能不好。但這種結構似乎更好:

{ 
    email: '[email protected]', 
    name: 'Person', 
    seenNews: [ 
    'TTJGGiPsTqqLio4sf', 
    'vhePmuShra3MSzYsu', 
    'JKFqqCKDmtuuoQBXu', 
    'gCFyzu8BAihj8NnXB' 
    ] 
} 

我可能不會有超過幾百新聞項目多,再加上我可以隨時回去,反正刪除舊的。

還是有更好的方法來處理這個問題嗎?

回答

1

鑑於你有新聞

{ 
    _id: "Fubar2.0", 
    title: "Fubar 2.0 released" 
} 

和用戶

{ 
    _id: "12345", 
    name: "CoolName" 
} 

存儲什麼在以上任一車型被視爲遲早會超過16MB的文件BSON大小限制。此外,使用mmapv1存儲引擎不能有效處理增加的文檔,該引擎仍然是默認設置。

結論:你需要在單獨的文檔閱讀新聞存儲看到集合中:

{ 
    _id: { 
    newsitem: "Fubar2.0", 
    user:"12345" 
    } 
} 

由於我們具有複合_id的看到,這是自動索引(並且只要在RAM中儘可能),查詢非常有效。

的問題是顯而易見的:你需要兩個查詢由用戶來獲取新聞看不見

var seen = new Array() 
db.seen.find({"_id.user":"12345"},{_id:1}).forEach(
    function(doc){ 
    seen.push(doc._id.news); 
    } 
) 
var unseen = db.news.find({_id: {$nin: seen}}) 

雖然這個工程恕我直言是描述的情況下的適當的解決方案,「看不見」的查詢是不是很高效。

根據不同的使用情況下,你可以比較像這樣的東西,爲用戶

{ 
    _id:"12345", 
    name: "CoolName", 
    lastSeen: ISODate("2015-05-05T03:26:36Z") 
} 

和新聞這樣

{ 
    _id:{ 
    title:"FuBar 2.0 released", 
    date: ISODate("2015-05-05T03:46:00Z") 
    } 
} 

因此,當用戶登錄,您已加載的用戶去文件,對嗎?有了這個,你可以得到所有的新聞,他或她可能還沒有與

db.news.find({"_id.date":{$gte: user.lastSeen} }) 

看到誠然,你不能真正檢查哪個用戶已經看到了這條新聞,但如果我們的目標是確保用戶在上次訪問後收到所有新聞,後一種解決方案效率高且易於實施(和擴展)。