如何在 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}}])