2016-01-14 428 views
1

我有一個樹狀模式,指定一個父母的集合和一個孩子的集合。如何加快MongoDB中的MongoDB查詢速度?

孩子的集合可能會有數以百萬計的文檔 - 其中每個文檔都包含少量數據,並且對其所屬的父類的引用存儲爲字符串(也許是我的第一個錯誤)。

收集的父母是小得多,但可能仍然在數以萬計,並會隨着時間的推移慢慢增長。一般來說,單親可能只有10個孩子,或多達5萬(可能更多,但不太可能)。

單個子文檔可能是這個樣子:

{ 
_id: ObjectId("507f191e810c19729de860ea"), 
info: "Here's some info", 
timestamp: 1234567890.0, 
colour: "Orange", 
sequence: 1000, 
parent: "12a4567b909c7654d212e45f" 
} 

其相應父記錄(其中居住在一個單獨的集合)可能是這個樣子:

{ 
_id: ObjectId("12a4567b909c7654d212e45f") 
info: "Blah", 
timestamp: 1234567890.0 
} 

我的貓鼬查詢(其中包含請求中的父ID)如下所示:

/* GET all children with the specified parent ID */ 
module.exports.childrenFromParent = function(req, res) { 
    parentID = req.params.parentID; 
    childModel.find({ 
     "parentid": parentID 
    }).sort({"sequence": "asc"}).exec(
     function(err, children) { 
      if (!children) { 
       sendJSONResponse(res, 404, { 
        "message": "no children found" 
       }); 
       return; 
      } else if (err) { 
       sendJSONResponse(res, 404, err); 
       return; 
      } 
      sendJSONResponse(res, 200, children); 
     } 
    ); 
}; 

因此基本上發生了什麼事情是查詢必須搜索具有與提供的ID匹配的父項的任何文檔的兒童的整個集合。

我目前將這個父ID作爲字符串保存在子集合模式(上面代碼中的childModel)中,這可能是一個壞主意,但是,我的API在請求中提供了父ID作爲字符串。

如果任何人有任何想法可以修復我的模式或更改查詢以提高性能,將不勝感激!

+0

你對「父」字段有任何索引嗎? – risyasin

+0

@risyasin不,沒有。 – Novark

+2

我建議你在父項上創建一個索引來幫助加快查詢速度。有關更多信息,請參閱https://docs.mongodb.org/v3.0/core/indexes-introduction/。 –

回答

1

從註釋寫了起來:

你可以幫助加快,並通過在parent場添加索引優化查詢。您可以通過執行以下添加(升序)指數:

db.collection.createIndex({ parent: 1 }) 

您可以通過添加.explain("executionStats")的查詢分析索引的好處。有關更多信息,請參閱docs

db.currentOp(
    { 
     $or: [ 
     { op: "query", "query.createIndexes": { $exists: true } }, 
     { op: "insert", ns: /\.system\.indexes\b/ } 
     ] 
    } 
) 

編輯:如果你是sequence排序,你可能要添加一個compound index

上的大集合添加一個索引可能需要一段時間,你可以通過運行下面的查詢檢查狀態parentsequence

+0

當我在子數據庫上發出getIndexes()查詢(在將「parentid」添加爲索引後)時,似乎有兩個索引:「_id」和「parentid」。我假設默認情況下「_id」總是存在,因爲mongoDB默認使用該鍵索引,但是,知道使用「parentid」鍵作爲索引以加快查詢時間足夠智能嗎? – Novark

+0

編輯到我以前的評論:是的,在我的查詢上運行解釋(「executionStats」)後,它看起來好像它正在使用「parentid」鍵作爲索引。我現在使用的是虛擬DB,因此我必須在生產數據庫上再次運行它,但是,我希望這會加快查詢的速度。 – Novark

+0

您可以使用'.hint()'強制使用索引,請參閱[here](https://docs.mongodb.org/manual/reference/method/cursor.hint/)。如果您發現我的答案有用,請接受它作爲解決方案。 –

0

爲什麼在執行exec之前不使用.lean()?你真的希望你所有的文件都是Mongoose文件嗎?或者只是簡單的JSON文件?隨着精益()你不會得到所有與Mongoose文檔一起來的額外的getter和setter。這可以很容易地從響應時間中刪除至少一兩秒。