MongoDB 性能问题,可能是由于投影在 NodeJS 项目中被忽略,使用本机 MongoDB 驱动程序

MongoDB performance issue, probably due to projection getting ignored in NodeJS project, using native MongoDB driver

长版本:(向下滚动查看 TLDR)

我有一个collection'libraries'。库可能是 "template" 或 "standard-template" 类型(在这种情况下)。如果它由一个组织拥有,它将包含一个 "organization_id"(否则为空),如果它是无主的,但一个组织可以访问它,这个 id 将被添加到一个 "organizations" 数组中。类型为 "template" 的库总是被拥有,类型为 "standard-template" 的库永远不会被拥有。 这样做的查询如下所示:

{
    "$or": [{
        "organization_id": id,
        "type": "template"
    }, {
        "organization_id": null,
        "type": "standard-template",
        "organizations": id
    }]
}

我有一个像 {"organization_id": 1, "type": 1} 这样的索引,而且没有很多 "standard-template" 库。 解释会告诉我这个查询需要 +- 4ms 来执行和 returns 50 个文档。

在我的 NodeJS 应用程序中,大约需要 12 秒。这可能是由于每个文档的大小(可能从几 KB 到 10MB 不等)。

我正在尝试使用投影将其限制为仅接收相关字段,但是,这似乎被完全忽略了。 我尝试了以下代码的各种变体,但 none 似乎有所不同。

TLDR

我的代码中的投影值似乎被忽略了。在示例中,我尝试仅检索“_id”字段,但最终得到了整个文档。

用于测试的代码

let id = ObjectID('5e56503cafc87b893b92827c');
let start = performance.now();
let find = mongodb.collection('libraries').find(
    {
        "$or": [
            {"organization_id": id, "type": "template"},
            {"organization_id": null,"type": "standard-template", "organizations": id}
        ]
    }, {_id: 1});

while (await find.hasNext()) {
    const doc = await find.next();
    console.log(doc); //HUGE! way more than just _id!
}

console.log(performance.now() - start); //about 12000 ms

更短的测试代码:

console.log(await mongodb.collection('libraries').findOne({}, {_id: 1})); //HUGE!

在我发现的任何示例或文档中,似乎都是以相同的方式完成的。我很确定我过去就是这样做的。 我在监督什么吗?非常感谢任何见解。

由于您使用游标遍历记录,因此需要链接项目函数以应用投影。你正在做的方式忽略了投影。您的代码应如下所示

et id = ObjectID('5e56503cafc87b893b92827c');
let start = performance.now();
let find = mongodb.collection('libraries').find(
    {
        "$or": [
            {"organization_id": id, "type": "template"},
            {"organization_id": null,"type": "standard-template", "organizations": id}
        ]
    }).project({_id: 1}); // this is the projection

while (await find.hasNext()) {
    const doc = await find.next();
    console.log(doc); //HUGE! way more than just _id!
}

console.log(performance.now() - start); //about 12000 ms

你可以像这样属性将投影包裹在投影中

{"projection": {"_id": 1}}

两者都应该有效。