根据 MongoDB 中的值执行条件 $lookup?

Do a conditional $lookup depending of a value in MongoDB?

我在 MongoDB 4.0 (pymongo)

中有三个合集
users: [
{name: "John", user_type: "client", society: 1},
{name: "Charles", user_type: "client", society: 1},
{name: "Jessy", user_type: "provider", society: 1},
{name: "Tim", user_type: "provider", society: 2}
]

clients: [
{_id: 1, name: "Client1"}
]

providers: [
{_id: 1, name: "Provider1"},
{_id: 2, name: "Provider2"}
]

我需要根据 user_type 值在用户和客户或提供者之间进行连接,并在结果中将其设置为相同的键值。

例如,结果将是:

user : {name: "John", user_type: "client", society: 1, complete_society: {_id: 1, name: "Client1"}}

or

user : {name: "Tim", user_type: "provider", society: 2, complete_society: {_id: 2, name: "Provider2"}}

我现在唯一的解决办法是在两个不同的键中做两个不同的$lookup,然后在请求后重新处理结果

db.users.aggregate([{                                   
  "$lookup": {
    "from": "clients",
    "localField": "society",
    "foreignField": "_id",
    "as": "client"
  }
},
{"$unwind": "$clients"},{                                   
  "$lookup": {
    "from": "providers",
    "localField": "society",
    "foreignField": "_id",
    "as": "provider"
  }
},
{"$unwind": "$providers"}]);

然后执行 forEach 并设置一个键 complete_society 并删除以前的键。这不是完美的方式,也许在 mongo 中,存在一些东西可以做到这一点。

您可以按照以下更改查询以获得预期结果,

  • 删除 $unwind 个阶段
  • $project 显示必填字段
  • $arrayElemAt 从查找结果中获取第一个元素
  • $cond 检查 user_type 是“客户端”然后 return client 数组否则 return provider 数组
db.users.aggregate([
  {
    $lookup: {
      from: "clients",
      localField: "society",
      foreignField: "_id",
      as: "client"
    }
  },
  {
    $lookup: {
      from: "providers",
      localField: "society",
      foreignField: "_id",
      as: "provider"
    }
  },
  {
    $project: {
      name: 1,
      society: 1,
      user_type: 1,
      complete_society: {
        $arrayElemAt: [
          {
            $cond: [{ $eq: ["$user_type", "client"] }, "$client", "$provider"]
          },
          0
        ]
      }
    }
  }
])

Playground