Группировать по 2 полям как 1 поле
Я пытаюсь сгруппировать пользователей по их основным и второстепенным ролям и подсчитать количество пользователей с указанными ролями. Список пользователей выглядит так:
[
{
_id: 1,
roles: {
primary: 'Cook',
secondary: null
}
},
{
_id: 2,
roles: {
primary: 'Waiter',
secondary: 'Cashier'
}
},
{
_id: 3,
roles: {
primary: 'Cashier',
secondary: 'Bar Tender'
}
}
]
И результат должен быть примерно таким:
[
{
role: 'Cook',
count: 1
},
{
role: 'Waiter',
count: 1
},
{
role: 'Cashier',
count: 2
}
]
Я не совсем уверен, если это вообще возможно сделать, по крайней мере, в одном $group
вызов.
1 ответ
Решение
Вы можете поместить оба значения поля в массив, $unwind
а потом $group
:
db.collection('crap').aggregate([
{ "$project": {
"roles": {
"$filter": {
"input": ["$roles.primary","$roles.secondary"],
"cond": { "$ne": [ "$$this", null ] }
}
}
}},
{ "$unwind": "$roles" },
{ "$group": {
"_id": "$roles",
"count": { "$sum": 1 }
}}
])
Мы используем $filter
удалить любой null
значения в проецируемом массиве.
На документах в вопросе это даст вам:
{
"_id" : "Bar Tender",
"count" : 1.0
}
{
"_id" : "Waiter",
"count" : 1.0
}
{
"_id" : "Cashier",
"count" : 2.0
}
{
"_id" : "Cook",
"count" : 1.0
}