首页 > 解决方案 > 根据 MongoDB 中的值进行条件 $lookup 吗?

问题描述

我在 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 中,有一些东西可以做到这一点。

标签: mongodbaggregation-frameworkpymongo

解决方案


您可以按以下方式更改您的查询以达到您的预期结果,

  • 删除$unwind阶段
  • $project显示必填字段
  • $arrayElemAt从查找结果中获取第一个元素
  • $cond检查user_type是“客户端”然后返回client数组,否则返回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
        ]
      }
    }
  }
])

操场


推荐阅读