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

Posted

技术标签:

【中文标题】根据 MongoDB 中的值进行条件 $lookup 吗?【英文标题】:Do a conditional $lookup depending of a value in MongoDB? 【发布时间】: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 中,有一些东西可以做到这一点。

【问题讨论】:

【参考方案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 方法将始终返回一个数组,我认为没有其他方法可以仅获取对象。

以上是关于根据 MongoDB 中的值进行条件 $lookup 吗?的主要内容,如果未能解决你的问题,请参考以下文章

如何根据数据框中的值有条件地对数据进行分组?

mongoDB表与表的关系及聚合管道查询

mongodb 怎么查询树形结构

在 MongoDB 中,如何根据对象的值对对象进行排序?

Mongodb:按元素分组并根据条件显示子文档计数并按日期对文档进行排序

MongoDb:如何根据每个字段的值更新多个文档中的字段值?