Использование $group и фильтрация запросов вместе
У меня есть коллекция такого рода
{
"_id" : <id>,
"USER" : <user1>,
"LIST" : <array>,
"TIME" : 1234
},
{
"_id" : <user1>,
"USER" : <id>,
"LIST" : <array>,
"TIME" : 1233
},
{
"_id" : <user3>,
"USER" : <id>,
"LIST" : <array>,
"TIME" : 1230
},
{
"_id" : <id>,
"USER" : <user4>,
"LIST" : <array>,
"TIME" : 1234
},
{
"_id" : <user5>,
"USER" : <id>,
"LIST" : <array>,
"TIME" : 1233
},
В конце я хочу массив этих документов, но сгруппированных по TIME
поле, т. е. если два TIME
поля одинаковы, они должны быть в одном объекте. Я также хочу, чтобы он был отфильтрован USER
поле. Я должен быть в состоянии передать массив, и должны быть переданы только те документы, которые имеют значения в массиве. Например, если я передам массив [user1, user2]
он должен передавать только результаты, сгруппированные по времени, которые также имеют пользовательские значения user1
или же user2
, Было бы неплохо также подсчитать количество документов в группе.
как например
переданный массив: [user1, user4]
[
{
"TIME": 1234,
"COUNT" : 2
},
{
"TIME": 1233,
"COUNT" : 1
}
]
Как мне это сделать? $in
является оператором запроса и $group
является агрегатным оператором. Я ищу способ объединить эти два.
2 ответа
db.collection.aggregate(
// Pipeline
[
// Stage 1
{
$match: {
USER: {
$in: ['user1', 'user4']
}
}
},
// Stage 2
{
$group: {
_id: {
TIME: '$TIME'
},
COUNT: {
$sum: 1
}
}
},
// Stage 3
{
$project: {
TIME: '$_id.TIME',
COUNT: 1,
_id: 0
}
},
]
);
Как сказал Нейл в комментарии, вы можете использовать конвейер агрегации следующим образом:
db.YourCollection.aggregate([
{$match: {_id: {$in: arrayOfIds}}},
{$project: {
TIME: "$TIME"
}},
{$group: {
_id: null,
TIME: "$TIME",
COUNT: {$sum: 1}
}}
]);