【问题标题】:Do a conditional $lookup depending of a value in MongoDB?根据 MongoDB 中的值进行条件 $lookup 吗?
【发布时间】:2021-12-06 06:11:03
【问题描述】:

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

【问题讨论】:

    标签: mongodb aggregation-framework pymongo


    【解决方案1】:

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

    • 删除$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
            ]
          }
        }
      }
    ])
    

    Playground

    【讨论】:

    • 非常感谢,还有一个问题:)。聚合给一个数组,但有时我只有一个结果(比如一个find_one),如果它存在一些不能做的事情列表(db.users...)[0],将不胜感激
    • @yassinekhelifa aggregate 方法将始终返回一个数组,我认为没有其他方法可以仅获取对象。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-10-05
    • 2020-09-07
    • 2021-02-22
    • 2019-02-04
    • 2020-05-11
    • 1970-01-01
    • 2016-11-14
    相关资源
    最近更新 更多