mongodb - $lookup 管道比预期慢
问题描述
我有以下$lookup
聚合阶段:
{
$lookup: {
from: "target",
let: {byTargetId: "$foreignTargetId"},
pipeline: [
{
$match: {
$expr: {
$eq: ["$targetId", "$$byTargetId"]
}
}
},
{
$project: {
someTargetProperty: true
}
}
],
as: "targets"
}
}
在我的测试数据库中,在此之前的阶段仅返回 5 个文档。在这种情况下,这些都没有可选属性foreignTargetId
,所以我希望byTargetId
每次undefined
都是这样,并且target
集合中的任何文档都不会匹配。
问题是,如果我添加这个查找阶段(最后),聚合需要 1 秒的时间。
target
如果我在与查找管道相同的集合上执行此聚合,其undefined
值为byTargetId
:
db.getCollection('target').aggregate(
[
{
$match: {
$expr: {
$eq: ["$targetId", undefined]
}
}
},
{
$project: {
someTargetProperty: true
}
}
])
那么这确实需要大约 200 毫秒,并且 5x200 毫秒 = 1 秒,所以这是有道理的。
null
但是,如果我使用以下值执行相同的聚合byTargetId
:
db.getCollection('target').aggregate(
[
{
$match: {
$expr: {
$eq: ["$targetId", null]
}
}
},
{
$project: {
someTargetProperty: true
}
}
])
然后在 < 1ms 内执行。
null
是什么导致和上的相等匹配之间存在如此大的差异undefined
?foreignTargetId
如果此阶段的输入文档中没有$lookup 阶段,我该如何跳过?
顺便说一句,我在这里使用查找管道的原因是其中的文档target
非常大,我只需要someTargetProperty
它也在索引中,因此查找可以完全在内存中完成。我注意到在其他情况下,这比查找整个文档并稍后进行投影要快得多。我不会接受试图通过不使用带有管道的 $lookup 来解决此问题的答案。
解决方案
推荐阅读
- c++ - 在arduino上删除数字的数组
- batch-file - 谁能帮我看看这个?
- amazon-dynamodb - 如何使用 OR 条件扫描 AWS 控制台中的发电机表?
- python - Matplotlib 带注释的热图格式
- php - 尝试使用 Angular 7 和 php 发送电子邮件时出现连接错误被拒绝
- python - 如何使用在 python 中的路径中有 $ 的地址
- windows - 在 Windows 10 上安装 VB6 应用程序时缺少 Dll
- react-native - 手风琴中的对齐箭头反应本机
- twilio - 如何在自动驾驶仪 Twilio 中重置流程?
- mongodb - Mongoose:在一个数组中查询另一个数组的值