如何在Mongoose中加速MongoDB查询?

时间:2016-01-14 21:51:27

标签: node.js mongodb rest express mongoose

我有一个类似树的架构,它指定了一组父母和一组孩子。

子集合可能包含数百万个文档 - 每个文档都包含少量数据,并且对它所属的父项的引用存储为字符串(可能是我的第一个错误)。

父母的收集要小得多,但可能仍然数万,并会随着时间的推移慢慢增长。一般来说,单亲家长可能只有10个孩子,或多达50,000个孩子(可能更多,但有些不太可能)。

单个子文档可能如下所示:

{
_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
}

我在mongoose中的查询(包含请求中的父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作为字符串。请求。

如果有人对如何修复我的架构或更改查询以提高性能有任何想法,我们将不胜感激!

2 个答案:

答案 0 :(得分: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排序,则可能需要为parentsequence添加compound index

答案 1 :(得分:1)

你为什么不在你的执行官之前使用.lean()?您真的希望所有文档都是Mongoose文档或只是简单的JSON文档吗?使用lean(),您将无法获得Mongoose文档附带的所有额外的getter和setter。这可以轻松地从响应时间中减少一两秒钟。