у меня проблема с фреймворком агрегации в MongoDB (mongoose) вот в чем проблема. У меня есть следующая схема базы данных. Поэтому я хочу подсчитать количество людей, у которых есть доступ только через Mobile
, только Card
или и то, и другое. без всякого порядка,
{
'_id': ObjectId,
'user_access_type': ['Mobile' , 'Card']
}
{
'_id': ObjectId,
'user_access_type': ['Card' , 'Mobile']
}
{
'_id': ObjectId,
'user_access_type': ['Mobile']
}
{
'_id': ObjectId,
'user_access_type': ['Card']
}
Теперь я использую это, но оно группируется только по порядку массива user_access_type
,
[ { "$group" : { "_id": {"User" : "$user_access_type"} , "count": {"$sum" : 1} }]
это вывод:
{
"_id": {
"User": [
"Card",
"Mobile"
]
},
"count": 1
},
{
"_id": {
"_id": "5f7dce2359aaf004985f98eb",
"User": [
"Mobile",
"Card"
]
},
"count": 1
},
{
"_id": {
"User": [
"Mobile"
]
},
"count": 1
},
{
"_id": {
"User": [
"Card"
]
},
"count": 1
},
против того, что я хочу:
{
"_id": {
"User": [
"Card",
"Mobile" // we can say both
]
},
"count": 2 // does not depend on order
},
{
"_id": {
"User": [
"Mobile"
]
},
"count": 1
},
{
"_id": {
"User": [
"Card"
]
},
"count": 1
},
Вы также можете использовать другой вариант, используя $function
,
$function
можно добавить javascript
код, вы можете использовать sort()
для сортировки массиваdb.collection.aggregate([
{
$addFields: {
user_access_type: {
$function: {
body: function(user_access_type){
return user_access_type.sort();
},
args: ["$user_access_type"],
lang: "js"
}
}
}
},
{
$group: {
_id: "$user_access_type",
count: { $sum: 1 }
}
}
])
Второй вариант,
Если массив user_access_type
всегда содержит уникальные элементы, вы можете использовать оператор $setUnion
для массива user_access_type
как самообъединение, каким-то образом это изменит порядок массива в том же порядке,
db.collection.aggregate([
{
$addFields: {
user_access_type: {
$setUnion: "$user_access_type"
}
}
},
{
$group: {
_id: "$user_access_type",
count: { $sum: 1 }
}
}
])