Групповой счет с MongoDB с использованием структуры агрегации
Скажем, моя схема MongoDB выглядит так:
{car_id: "...", owner_id: "..."}
Это отношение много-ко-многим. Например, данные могут выглядеть так:
+-----+----------+--------+
| _id | owner_id | car_id |
+-----+----------+--------+
| 1 | 1 | 1 |
| 2 | 1 | 2 |
| 3 | 1 | 3 |
| 4 | 2 | 1 |
| 5 | 2 | 2 |
| 6 | 3 | 4 |
| 7 | 3 | 5 |
| 8 | 3 | 6 |
| 9 | 3 | 7 |
| 10 | 1 | 1 | <-- not unique
+-----+----------+--------+
Я хочу получить количество автомобилей, принадлежащих каждому владельцу. В SQL это может выглядеть так:
SELECT owner_id, COUNT(*) AS cars_owned
FROM (SELECT owner_id FROM car_owners GROUP BY owner_id, car_id) AS t
GROUP BY owner_id;
В этом случае результат будет выглядеть так:
+----------+------------+
| owner_id | cars_owned |
+----------+------------+
| 1 | 3 |
| 2 | 2 |
| 3 | 4 |
+----------+------------+
Как я могу выполнить то же самое с помощью MongoDB с использованием структуры агрегации?
Ответы
Ответ 1
Чтобы разместить потенциальные дубликаты, вам нужно использовать две операции $group
:
db.test.aggregate([
{ $group: {
_id: { owner_id: '$owner_id', car_id: '$car_id' }
}},
{ $group: {
_id: '$_id.owner_id',
cars_owned: { $sum: 1 }
}},
{ $project: {
_id: 0,
owner_id: '$_id',
cars_owned: 1
}}]
, function(err, result){
console.log(result);
}
);
Дает результат в формате:
[ { cars_owned: 2, owner_id: 10 },
{ cars_owned: 1, owner_id: 11 } ]
Ответ 2
$group
похож на команду SQL Group по команде. В приведенном ниже примере мы собираемся объединить компании на основе того года, в котором они были основаны. И рассчитайте среднее число сотрудников для каждой компании.
db.companies.aggregate([{
$group: {
_id: {
founded_year: "$founded_year"
},
average_number_of_employees: {
$avg: "$number_of_employees"
}
}
}, {
$sort: {
average_number_of_employees: -1
}
}
])
![$avg operator MongoDB]()
Этот конвейер агрегации имеет 2 этапа
Теперь фундаментальным для этапа $group
является поле _id
, которое мы укажем как часть документа. Это значение самого оператора $group
, использующего очень строгую интерпретацию синтаксиса каркасной структуры. _id
заключается в том, как мы определяем, как мы контролируем, как мы настраиваем то, что использует групповой этап для организации документов, которые он видит.
В приведенном ниже запросе найдите отношения людей с компаниями, использующими оператор $sum
:
db.companies.aggregate([{
$match: {
"relationships.person": {
$ne: null
}
}
}, {
$project: {
relationships: 1,
_id: 0
}
}, {
$unwind: "$relationships"
}, {
$group: {
_id: "$relationships.person",
count: {
$sum: 1
}
}
}, {
$sort: {
count: -1
}
}])
![$sum in MongoDB]()