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.