【问题标题】:How can I speed up this MongoDB query in Mongoose?如何在 Mongoose 中加速这个 MongoDB 查询?
【发布时间】:2016-04-20 10:05:28
【问题描述】:

我有一个树状架构,它指定了一组父项和一组子项。

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

父母的集合要少得多,但可能仍然在数万之内,并且会随着时间的推移慢慢增长。不过一般来说,单亲父母可能有少至 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 作为字符串提供。

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

【问题讨论】:

标签: node.js mongodb rest express mongoose


【解决方案1】:

你为什么不在你的 exec 之前使用 .lean() ?您真的希望所有文档都是 Mongoose 文档还是简单的 JSON 文档?使用lean(),您将不会获得Mongoose 文档附带的所有额外的getter 和setter。这可以轻松地将响应时间缩短至少一两秒。

【讨论】:

    【解决方案2】:

    从 cmets 写下来:

    您可以通过在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

    【讨论】:

    • 当我对我的子数据库发出 getIndexes() 查询(添加“parentid”作为索引之后),似乎有 2 个索引:“_id”和“parentid”。我假设默认情况下始终存在“_id”,因为 mongoDB 默认对该键进行索引,但是,知道使用“parentid”键作为索引以加快查询时间是否足够聪明?跨度>
    • 编辑我之前的评论:是的,在我的查询上运行 explain("executionStats") 之后,它看起来好像它使用“parentid”键作为预期的索引。我目前正在使用一个虚拟数据库,所以我必须在生产数据库上再次运行它,但是,我希望这会加快查询速度。
    • 您可以使用.hint() 强制使用索引,请参阅here。如果您发现我的回答有用,请接受它作为解决方案。
    • 感谢您的提示。我已接受您的回答作为解决方案。
    猜你喜欢
    • 2018-07-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-10
    • 2015-07-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多