繁体   English   中英

使用聚合$ lookup和$ mergeObjects

[英]Using aggregate $lookup and $mergeObjects

我想加入收藏。 之前,我只使用查找,这样我就可以得到连接的分隔字段。 但我需要得到类似mysql join的结果。 我注意到这个动作有$ lookup和$ mergeObjects,但效果不好。

用户集合模型。

{
    "_id": ObjectId("xxxxxxx"), //this is default id from mongoDB
    "name": 'admin user',
    "email": 'admin@test.com',
    "password": 'xxxxxxxx',
    "roles": [
        {
            "id": 0,
            "approved": true
        },{
            "id": 2,
            "approved": true
        }
    ]
},{
    "_id": ObjectId("xxxxxxx"), //this is default id from mongoDB
    "name": 'userOne',
    "email": 'user@test.com',
    "password": 'xxxxxxxx',
    "roles": [
        {
            "id": 1,
            "approved": true
        }
    ]
}

角色集合模型。

{
    "_id": ObjectId("xxxxxxx"), //this is default id from mongoDB
    "id": '0',
    "name": 'administrator'
},{
    "_id": ObjectId("xxxxxxx"), //this is default id from mongoDB
    "id": '0',
    "name": 'employeer'
},{
    "_id": ObjectId("xxxxxxx"), //this is default id from mongoDB
    "id": '0',
    "name": 'freelancer'
} 

加入后,我希望获得如下结果。

{
    "_id": ObjectId("xxxxxxx"), //this is default id from mongoDB
    "name": 'admin user',
    "email": 'admin@test.com',
    "password": 'xxxxxxxx',
    "roles": [
        {
            "id": 0,
            "name": "administrator",    //join result
            "approved": true
        },{
            "id": 2,
            "name": "freelancer",       //join result
            "approved": true
        }
    ]
},{
    "_id": ObjectId("xxxxxxx"), //this is default id from mongoDB
    "name": 'userOne',
    "email": 'user@test.com',
    "password": 'xxxxxxxx',
    "roles": [
        {
            "id": 1,
            "name": "employeer",        //join result
            "approved": true
        }
    ]
}

您可以使用以下aggregation与mongodb 3.4

您需要首先$unwind roles数组,然后再$group再次回滚

db.users.aggregate([
  { "$unwind": "$roles" },
  { "$lookup": {
    "from": "roles",
    "localField": "roles.id",
    "foreignField": "id",
    "as": "roles.role"
  }},
  { "$unwind": "$roles.role" },
  { "$addFields": {
    "roles": { "$mergeObjects": ["$roles.role", "$roles"] }
  }},
  { "$group": {
    "_id": "$_id",
    "email": { "$first": "$email" },
    "password": { "$first": "$password" },
    "roles": { "$push": "$roles" }
  }},
  { "$project": { "roles.role": 0 }}
])

使用mongodb 3.6及以上版本非常简单

db.users.aggregate([
  { "$unwind": "$roles" },
  { "$lookup": {
    "from": "roles",
    "let": { "roleId": "$roles.id", "approved": "$roles.approved" },
    "pipeline": [
      { "$match": { "$expr": { "$eq": ["$id", "$$roleId"] }}},
      { "$addFields": { "approved": "$$approved" }}
    ],
    "as": "roles"
  }},
  { "$unwind": "$roles" },
  { "$group": {
    "_id": "$_id",
    "email": { "$first": "$email" },
    "password": { "$first": "$password" },
    "roles": { "$push": "$roles" }
  }}
])

两者都会给你类似的输出

[
  {
    "_id": ObjectId("5a934e000102030405000004"),
    "email": "user@test.com",
    "password": "xxxxxxxx",
    "roles": [
      {
        "_id": ObjectId("5a934e000102030405000001"),
        "approved": true,
        "id": 1,
        "name": "employeer"
      }
    ]
  },
  {
    "_id": ObjectId("5a934e000102030405000003"),
    "email": "admin@test.com",
    "password": "xxxxxxxx",
    "roles": [
      {
        "_id": ObjectId("5a934e000102030405000000"),
        "approved": true,
        "id": 0,
        "name": "administrator"
      },
      {
        "_id": ObjectId("5a934e000102030405000002"),
        "approved": true,
        "id": 2,
        "name": "freelancer"
      }
    ]
  }
]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM