Cara paling "berperforma" untuk melakukannya adalah dengan melewati $unwind
sama sekali dan cukup $group
untuk menghitung. Pada dasarnya array "filter" mendapatkan $size
dari hasil ke $sum
:
db.objects.aggregate([
{ "$match": {
"createddate": {
"$gte": ISODate("2015-08-30T00:00:00.000Z")
},
"activity.action": "test_action"
}},
{ "$group": {
"_id": null,
"count": {
"$sum": {
"$size": {
"$setDifference": [
{ "$map": {
"input": "$activity",
"as": "el",
"in": {
"$cond": [
{ "$eq": [ "$$el.action", "test_action" ] },
"$$el",
false
]
}
}},
[false]
]
}
}
}
}}
])
Rilis MongoDB mendatang akan memiliki $filter
, yang membuatnya jauh lebih sederhana:
db.objects.aggregate([
{ "$match": {
"createddate": {
"$gte": ISODate("2015-08-30T00:00:00.000Z")
},
"activity.action": "test_action"
}},
{ "$group": {
"_id": null,
"count": {
"$sum": {
"$size": {
"$filter": {
"input": "$activity",
"as": "el",
"cond": {
"$eq": [ "$$el.action", "test_action" ]
}
}
}
}
}
}}
])
Menggunakan $unwind
menyebabkan dokumen menjadi tidak normal dan secara efektif membuat salinan per entri array. Jika memungkinkan, Anda harus menghindari hal ini karena biaya yang sering kali ekstrem. Memfilter dan menghitung entri array per dokumen jauh lebih cepat jika dibandingkan. Seperti $match
simple sederhana dan $group
pipeline dibandingkan dengan banyak tahapan.