【问题标题】:MongoDB - use document field as variableMongoDB - 使用文档字段作为变量
【发布时间】:2020-06-11 16:24:29
【问题描述】:

我有类似结构的文档:

{
    users_ids: [
        "122djdj-sdsddsl-3232323",
        "2332333-443rdds-sdadads"
    ],
    users_roles: {
        "122djdj-sdsddsl-3232323": "admin",
        "2332333-443rdds-sdadads": "moderator"
    },
    users_names: {
        "122djdj-sdsddsl-3232323": "John Smith",
        "2332333-443rdds-sdadads": "Paul Newman"
    }
}

users_ids 是包含用户的数组,然后是具有不同属性的对象。 现在,我想查询并获取包含以下附加字段的文档:

adminId: 122djdj-sdsddsl-3232323
adminName: John Smith

所有这些字段都是非动态的,即在查询中定义。 我需要他们使用例如管理员名称对值进行排序(所以我首先必须知道谁是管理员,然后添加具有管理员名称的字段)。 我的问题:如何在其他表达式中使用文档中的字段?我想先添加字段:

{
    $addFields: {
        userA: { $arrayElemAt: ["$users_ids", 0] },
        userB: { $arrayElemAt: ["$users_ids", 1] },
    }
}

然后在其他条件下使用 $userA 和 $userB - 但是任何方法都不起作用,还尝试了 $objectToArray 没有成功:

{
    $addFields: {
        roles: { $objectToArray: "$users_roles" }
    }
},
{
    $addFields: {
        // Doesnt work
        adminName: {
            $cond: {
                if: {
                    $eq: ["$roles[0].v", 'admin']
                },
                then: "$roles[0].k",
                else: "$roles[1].k"
            }
        }
    }
}

【问题讨论】:

    标签: mongodb mongodb-query aggregation-framework aggregation


    【解决方案1】:

    您必须从 $objectToArray 开始,因为您的键名是动态的(您可以重新考虑该设计)。然后你需要运行$arrayElemAt$filter 的组合来获得第一个匹配元素:

    db.collection.aggregate([
        {
            $addFields: {
                user_roles_arr: { $objectToArray: "$users_roles" },
                user_names_arr: { $objectToArray: "$users_names" },
            }
        },
        {
            $addFields: {
                admin: {
                    $arrayElemAt: [
                        { $filter: { input: "$user_roles_arr", cond: { $eq: [ "$$this.v", "admin" ] } } }, 0
                    ]
                }
            }
        },
        {
            $addFields: {
                adminId: "$admin.k",
                adminName: {
                    $let: {
                        vars: { adm: { $arrayElemAt: [ { $filter: { input: "$user_names_arr", cond: { $eq: [ "$admin.k", "$$this.k" ] } } }, 0 ]  } },
                        in: "$$adm.v"
                    }
                }
            }
        },
        {
            $project: {
                user_roles_arr: 0,
                user_names_arr: 0,
                admin: 0
            }
        }
    ])
    

    Mongo Playground

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-06-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-13
      • 1970-01-01
      相关资源
      最近更新 更多