2015-11-30 50 views
0

我正在重建我的網站,該網站是來自法國最活躍的論壇的暱稱搜索引擎:您搜索暱稱並獲得所有消息。Mongodb:大數據結構

我目前的數據庫包含超過60Gb的數據,存儲在MySQL數據庫中。我正在將它重寫到一個mongodb數據庫中,並且在檢索100萬條消息(1條消息= 1個文檔)後,find()開始需要一段時間。

文檔的結構是這樣:

{ 
    "_id" : ObjectId(), 
    "message": "<p>Hai guys</p>", 
    "pseudo" : "mahnickname", //from a nickname (*pseudo* in my db) 
    "ancre" : "774497928", //its id in the forum 
    "datepost" : "30/11/2015 20:57:44" 
} 

我設定的ID ancre作爲唯一的,所以我沒有得到兩次相同的條目。

然後用戶輸入暱稱並找到具有該暱稱的所有文檔。

這裏是要求:

Model.find({pseudo: "danickname"}).sort('-datepost').skip((r_page -1) * 20).limit(20).exec(function(err, bears)... 

我應該不同結構呢?每個消息都有一個文檔,而不是每個暱稱都有一個文檔,並且一旦我從該暱稱收到新消息,我就更新文檔?

我對MySQL使用第一種方法,並沒有花太多時間。

編輯:或者,也許我應該索引暱稱()?

謝謝!

+0

您應該爲'pseudo'添加一個索引。在這裏查看這個帖子,特別是選擇性領域:http://stackoverflow.com/questions/33545339/how-does-the-order-of-compound-indexes-matter-in-mongodb-performance-wise/33546159 #33546159 – inspired

+0

請注意,'skip'實際上必須解析它跳過的文檔,所以如果'r_page'真的很大,那麼'skip'將需要跳過一堆文檔。 –

+0

啊哈,我完全忘了索引暱稱。感謝隊友,我現在就試試 – Sinequanon

回答

1

這裏是你對大數據問題的一些建議:

  1. The ObjectId already contains a timestampYou can also sort on it。您可以通過刪除datepost字段來節省一些磁盤空間。
  2. 你絕對需要ancre字段嗎? ObjectId已經是唯一的並且被索引。如果您絕對需要它,並且需要保持datepost的分離率,則可以將_id字段替換爲您的ancre字段。
  3. 正如許多人所提到的,您應該在pseudo上添加索引。這將使得「獲取所有僞名爲mahnickname的郵件」的搜索速度更快。
  4. 如果每個用戶的郵件數量很少,則可以將每個用戶的所有郵件存儲在單個文檔中。這將避免跳轉到特定的頁面,這可能會很慢。但是,請注意16mb limit。我個人仍然有他們在多個文件。
  5. 要保持快速的查詢速度,請確保您的所有indexed fields fit in RAM。通過鍵入db.collection.stats()並查看indexSizes子文檔,您可以看到索引字段的RAM消耗。
  6. 會有一種方法讓您不要跳過文檔,而是使用寫入數據庫的時間作爲頁面?如果是這樣,請使用datepost字段或_id中的時間戳作爲您的分頁策略。如果您決定使用datepost,請在pseudodatepost上撥打compound index

至於你的基準測試,你可以使用mongotopmongostat密切監控MongoDB。