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}}
两者都应该有效。
长版本:(向下滚动查看 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}}
两者都应该有效。