mongodb - 对集合的子集执行 $lookup
问题描述
我有这个数据
[
{"_id":0,"a":1,"b":1,"source":1},
{"_id":1,"a":1,"c":4,"source":1},
{"_id":2,"a":2,"d":6,"source":1},
{"_id":3,"a":2,"e":6,"source":1},
{"_id":4,"a":2,"f":6,"source":1},
{"_id":5,"a":3,"d":6,"source":1},
{"_id":6,"a":3,"b":1,"source":1},
{"_id":7,"a":3,"f":6,"source":1},
{"_id":8,"a":3,"qq":3,"source":2},
{"_id":9,"a":3,"fl":6,"source":2}
]
我想返回其a
字段等于具有a
字段的文档的字段的所有文档b
。此外,所有内容都必须来自源 1。
最终结果应该是这样的:
[
{"_id":0,a":1,"b":1,"source":1},
{"_id":1,"a":1,"c":4,"source":1},
{"_id":5,"a":3,"d":6,"source":1},
{"_id":6,"a":3,"b":1,"source":1},
{"_id":7,"a":3,"f":6,"source":1}
]
以下查询为我提供了我想要的结果:
myCollection.aggregate([{"$match":{"b":{"$exists":true},"source":1}},
{"$group":{"_id":null, "a":{"$addToSet":"$a"}}},
{"$unwind":{"path":"$a"}},
{"$project":{"_id":false}},
{"$lookup":
{"from": "myCollection",
"localField":"a",
"foreignField":"a",
"as":"results"}},
{"$project":{"a":false}},
{"$unwind":{"path":"$results"}},
{"$replaceRoot":{"newRoot":"$results"}},
{"$match":{"source":1}}
])
但是,必须添加最后一条{"$match":{"source":1}}
语句让我想到,对于大型数据集,该$lookup
语句会产生很多不需要的结果,然后会被我的最后一条$match
语句过滤掉。有没有办法通过限制 $lookup
来自 myCollection 的 source 等于 1 的文档来防止它们的生成?
即替换
{"$lookup":
{"from": "myCollection"
有类似的东西
{"$lookup":
{"from": myCollection.match({"source":1})
或者,我可以使用更高效的管道吗?
解决方案
$lookup
您可以过滤阶段管道中的少量文档。这将有助于获得一些性能并避免不必要的结果。你可以像下面这样使用它:
{
"$lookup": {
"from": "collection",
"let": {
a_: "$a"
},
"pipeline": [
{
"$match": {
$expr: {
$and: [
{
$eq: [
"$source",
1
]
},
{
$eq: [
"$a",
"$$a_"
]
}
]
}
}
}
],
"as": "results"
}
}
你的$project
舞台,
{"$project":{"a":false}}
其实没用,可以省略。
推荐阅读
- android - 用户界面停止工作
- chainer - Cupy错误安装
- c++ - 给定递归表达式,找到空间复杂度为 O(1) 的算法
- python - 如何从传递命名可选参数的命令行调用函数
- jquery-ui - 为什么以下 JQuery UI 代码无法删除已删除的元素?
- c++ - InitiateShutdown API 并不总是支持 SHUTDOWN_INSTALL_UPDATES 标志
- scala - 拆分 DataFrame Spark Scala
- r - 如何通过两个条件对 R 中的数据框进行子集化,然后将这些变量应用于回归?
- javascript - 如何使用css或js更改带有图标的文本
- swift - “无法将 '()' 类型的值转换为 UIImage”:Swift