如何在 MongoDB 中进行条件 $lookup
How to do a conditional $lookup in MongoDB
我有三个合集:A、B、C。
A 有一个名为 a 的 属性,它是 B 或 C 中的一个 ref id。
我想做的是,先在B中查找,如果没有找到,再在C中查找。
像这样:
[
{
$lookup:
{
from: 'B',
localField: 'a',
foreignField: '_id',
as: 'temp'
}
},
{
$unwind:
{
path: '$temp',
preserveNullAndEmptyArrays: true
}
},
{
$lookup:
{
if: 'temp not exist', <! just demonstrate !>
from: 'C',
localField: 'a',
foreignField: '_id',
as: 'temp'
}
},
]
我不知道如何实现这个。有人可以帮忙吗?谢谢
我认为我们不能做条件管道阶段(我们可以做条件运算符但不能做阶段),基于我们在查询 运行.
时获得的信息
*如果我们在编写查询时有信息,我们可以动态生成查询并包含或不包含阶段
但是您可以将 $lookup
与管道一起使用,并添加此过滤器,例如如果 temp 是空数组(意味着没有发生连接),则仅在那时连接。
我看不出有什么理由在中间展开,先进行 2 次查找,然后再进行。
查询
- 进行第一次查找
- 第二次查找是带有过滤器的管道,要求第一次查找临时数组为空
(如果你在中间保持放松,使用这个 {"$eq": [{"$type": "$temp"}, "missing"]}
而不是空检查)
- 保持为temp,temp或tempC取决于谁不为空
- 取消设置温度
- 现在是否展开(我认为在展开之前加入更快,它的文档更少),您还想先找到加入成员然后展开
aggregate(
[ {"$lookup":
{"from": "B", "localField": "a", "foreignField": "_id", "as": "temp"}},
{"$lookup":
{"from": "C",
"let": {"a": "$a", "temp": "$temp"},
"pipeline":
[{"$match":
{"$expr":
{"$and": [{"$eq": ["$temp", []]}, {"$eq": ["$a", "$_id"]}]}}}],
"as": "tempC"}},
{"$set": {"temp": {"$cond": [{"$eq": ["$temp", []]}, "$tempC", "$temp"]}}},
{"$unset": ["tempC"]},
{"$unwind": {"path": "$temp", "preserveNullAndEmptyArrays": true}}])
我有三个合集:A、B、C。
A 有一个名为 a 的 属性,它是 B 或 C 中的一个 ref id。
我想做的是,先在B中查找,如果没有找到,再在C中查找。
像这样:
[
{
$lookup:
{
from: 'B',
localField: 'a',
foreignField: '_id',
as: 'temp'
}
},
{
$unwind:
{
path: '$temp',
preserveNullAndEmptyArrays: true
}
},
{
$lookup:
{
if: 'temp not exist', <! just demonstrate !>
from: 'C',
localField: 'a',
foreignField: '_id',
as: 'temp'
}
},
]
我不知道如何实现这个。有人可以帮忙吗?谢谢
我认为我们不能做条件管道阶段(我们可以做条件运算符但不能做阶段),基于我们在查询 运行.
时获得的信息*如果我们在编写查询时有信息,我们可以动态生成查询并包含或不包含阶段
但是您可以将 $lookup
与管道一起使用,并添加此过滤器,例如如果 temp 是空数组(意味着没有发生连接),则仅在那时连接。
我看不出有什么理由在中间展开,先进行 2 次查找,然后再进行。
查询
- 进行第一次查找
- 第二次查找是带有过滤器的管道,要求第一次查找临时数组为空
(如果你在中间保持放松,使用这个{"$eq": [{"$type": "$temp"}, "missing"]}
而不是空检查) - 保持为temp,temp或tempC取决于谁不为空
- 取消设置温度
- 现在是否展开(我认为在展开之前加入更快,它的文档更少),您还想先找到加入成员然后展开
aggregate(
[ {"$lookup":
{"from": "B", "localField": "a", "foreignField": "_id", "as": "temp"}},
{"$lookup":
{"from": "C",
"let": {"a": "$a", "temp": "$temp"},
"pipeline":
[{"$match":
{"$expr":
{"$and": [{"$eq": ["$temp", []]}, {"$eq": ["$a", "$_id"]}]}}}],
"as": "tempC"}},
{"$set": {"temp": {"$cond": [{"$eq": ["$temp", []]}, "$tempC", "$temp"]}}},
{"$unset": ["tempC"]},
{"$unwind": {"path": "$temp", "preserveNullAndEmptyArrays": true}}])