MongoDB 单个 $lookup / 聚合查询以列出用户和用户分配为成员的团队

Posted

技术标签:

【中文标题】MongoDB 单个 $lookup / 聚合查询以列出用户和用户分配为成员的团队【英文标题】:MongoDB single $lookup / aggregate query to list users and the teams where the user assigned as a member 【发布时间】:2022-01-19 16:36:25 【问题描述】:

我想编写一个 $lookup 查询示例 User.aggregate([ $match ]).lookup(... 来列出具有额外键 _team 的用户,其中用户被分配为任何团队的成员。这是示例 mongo 集合 -

第一集

# Users Collection - 

    "_id": "1",
    "name": "Sankhnad"
,

    "_id": "2",
    "name": "Shweta"

第二集

# Teams Collection - 

    "_id": "1",
    "name": "Rock Team",
    "_members": [
        2
    ]
,

    "_id": "2",
    "name": "Star Team",,
    "_members": [
        1,
    ]
,

    "_id": "3",
    "name": "Yeh Team",
    "_members": [
        1,
        2
    ]

现在我想对 usersteams 集合进行单个 $lookup / aggregate 查询,以列出所有用户及其各自的团队或选定的用户及其所在用户所在的团队分配在_members

所有用户的预期输出 -

# Output - 

    "_id": "1",
    "name": "Sankhnad",
    "_teams": [
        
            "_id": "2",
            "name": "Star Team",,
            "_members": [
                1,
            ]
        ,
        
            "_id": "3",
            "name": "Yeh Team",
            "_members": [
                1,
                2
            ]
        
    ]
,

    "_id": "2",
    "name": "Shweta",
    "_teams": [
        
            "_id": "1",
            "name": "Rock Team",
            "_members": [
                2
            ]
        ,
        
            "_id": "3",
            "name": "Yeh Team",
            "_members": [
                1,
                2
            ]
        
    ]

非常感谢大家的支持。

【问题讨论】:

【参考方案1】:

我们可以做如下的事情-

db.users.aggregate([
$match: deleted: false, // Put condition in user collection if needed

    $lookup: 
        from: "teams",
        localField: "_id",
        foreignField: "_members",
        as: "team"
    
,
$unwind:  path: "$team", preserveNullAndEmptyArrays: true,
    
        $project:  // To show only the records that you want
        "_id": 1,
        "name": 1,
        "team._id": 1,
        "team.name": 1,
        "team._members": 1
        
    
]);

【讨论】:

【参考方案2】:

查询

查找可以在数组/单个值上工作,如果数组包含该值,就会进行查找。 (类似于查询 $eq 运算符) 因为您在字符串和数组中都有“_id”,所以也使用了数字$toInt

Test code here

users.aggregate(
["$set":"nid":"$toInt":"$_id",
 "$lookup":
  "from":"teams",
   "localField":"nid",
   "foreignField":"_members",
   "as":"_teams",
 "$unset":["nid"]])

【讨论】:

【参考方案3】:

您可以按照用户表中的 $lookup 使用您想要的用户的关联团队。

注意:_members id 应该是 string 而不是 int32 用于查找。如果不是字符串,则需要 type conversion

db.users.aggregate([$lookup:
  from: 'teams',
  localField: '_id',
  foreignField: '_members',
  as: 'teams'
])

使用查找管道的相同查询想要

db.users.aggregate[
  from: 'teams',
 let:ids:"$_id",
 pipeline:[
  $match:
    $expr:
    $in:["$$ids","$_members"]
  
  
 ],
  as: '_teams'
])

【讨论】:

以上是关于MongoDB 单个 $lookup / 聚合查询以列出用户和用户分配为成员的团队的主要内容,如果未能解决你的问题,请参考以下文章

MongoDB——聚合管道之$lookup操作

MongoDB在具有附加字段的对象数组上聚合$lookup

MongoDB在具有附加字段的对象数组上聚合$lookup

MongoDB 聚合 $lookup 不适用于 $group

Mongodb聚合$lookup $project和$match不起作用[重复]

Mongodb聚合$lookup $project和$match不起作用[重复]