【问题标题】:Mongodb $lookup aggregation returns all documents from foreign indexMongodb $lookup 聚合返回外部索引中的所有文档
【发布时间】:2021-03-09 18:27:06
【问题描述】:

我有一个用户索引

[{
 username: "foo@bar,
 roleIds: [ Types.ObjectId("1234") ]
},
{
 username: "foo@moo,
}]

roles

{
    "_id" : ObjectId("60465768f768621ec5828b68"),
    "name" : "admin",
    "permissionIds" : ObjectId("604657e8e715ss1f2d78b945")
}

permissions

{
    "_id" : ObjectId("604657e8e715ss1f2d78b945"),
    "name" : "view-user",
}

当我通过用户名获取用户时,我想补充角色信息。 并非所有用户都有 roleIds,所以无论用户是否有 roleIds,我都需要能够返回该用户。

目前,角色查找总是返回roles 索引中的每一项!

我的想法是通过数组roleIds_ids 查找加入索引rolesroles

然后我在该查找中流水线以从角色中获取权限信息。

db.getCollection('users').aggregate([
        {
          $match: {
            'username':'foo@bar',
          }
      },
        {
          $lookup: {
            from: 'roles',
            let: {'roleIds': '_id'},
            as: 'roles',
            pipeline: [{
                $lookup: {
                  from: 'permissions',
                  let: {'permissionIds': "_id"},
                  as: 'permissions',
                  pipeline: [
                    {
                      $project: {
                        name: 1
                      }
                    }
                  ]
                }
              },{
                $project: {
                  name: 1,
                  permissions: 1
                }
              }
            ]
          }
        }
      ])

这条路线似乎只是返回roles索引内的所有文档,无论它是否实际上是一个连接。

有什么我马上做错了吗??

【问题讨论】:

    标签: mongodb nosql aggregation-framework nosql-aggregation


    【解决方案1】:

    您的查询中有以下错误:

    1. 您在两个查找中都将错误的变量传递给 pipeline 内的 let
    2. 在执行实际连接操作的管道中缺少 $match 阶段。
    3. 使用ifNull 初始化空的roleIds[](因为所有用户都没有该字段)。

    试试这个查询:

    db.getCollection('users').aggregate([
        {
            $match: {
                'username': 'foo@bar',
            }
        },
        {
            $lookup: {
                from: 'roles',
                let: { 'roleIds': { $ifNull: ["$roleIds", []] } },
                as: 'roles',
                pipeline: [
                    {
                        $match: {
                            $expr: { $in: ["$_id", "$$roleIds"] }
                        }
                    },
                    {
                        $lookup: {
                            from: 'permissions',
                            let: { 'permissionId': "$permissionIds" },
                            pipeline: [
                                {
                                    $match: {
                                        $expr: { $eq: ["$_id", "$$permissionId"] }
                                    }
                                },
                                {
                                    $project: {
                                        name: 1
                                    }
                                }
                            ],
                            as: 'permissions'
                        }
                    },
                    {
                        $project: {
                            name: 1,
                            permissions: 1
                        }
                    }
                ]
            }
        }
    ]);
    

    【讨论】:

      猜你喜欢
      • 2016-12-19
      • 1970-01-01
      • 2018-06-13
      • 2023-03-30
      • 2023-03-05
      • 1970-01-01
      • 2022-01-05
      • 2021-07-27
      • 2020-12-31
      相关资源
      最近更新 更多