La façon la plus "performante" de le faire est d'ignorer le $unwind en tout et simplement $group compter. Essentiellement, les tableaux de "filtre" obtiennent la $size des résultats à $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]
]
}
}
}
}}
])
Les futures versions de MongoDB auront $filter , ce qui rend cela beaucoup plus simple :
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" ]
}
}
}
}
}
}}
])
Utiliser $unwind provoque la dénormalisation des documents et crée effectivement une copie par entrée de tableau. Dans la mesure du possible, vous devriez éviter cela en raison du coût souvent extrême. Le filtrage et le comptage des entrées de tableau par document sont beaucoup plus rapides en comparaison. Comme un simple $match et $group pipeline par rapport à de nombreuses étapes.