2016-01-14 123 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。这可以很容易地从响应时间中删除至少一两秒。