MongoDB - использовать поле документа в качестве переменной - PullRequest
1 голос
/ 27 февраля 2020

У меня есть документы со структурой, подобной этой:

{
    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

Все эти поля будут не динамическими c, т.е. будут определены в запросе. Мне нужно, чтобы они сортировали значения, используя, например, имя администратора (поэтому я сначала должен знать, кто такой администратор, а затем добавить поле с именем администратора). Мой вопрос: как я могу использовать поле из документа в других выражениях? Я думал о том, чтобы сначала добавить поля:

{
    $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"
            }
        }
    }
}

1 Ответ

1 голос
/ 27 февраля 2020

Вы должны начать с $objectToArray, поскольку имена ваших ключей являются динамическими c (вы можете переосмыслить этот дизайн). Затем вам нужно запустить комбинацию $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
        }
    }
])

Пн go Детская площадка

...