Cách "hiệu quả" nhất để làm điều này là bỏ qua $unwind altogther và đơn giản là $group để đếm. Về cơ bản, mảng "bộ lọc" nhận được $size trong số các kết quả đến $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]
]
}
}
}
}}
])
Các bản phát hành trong tương lai của MongoDB sẽ có $filter , điều này làm cho việc này trở nên đơn giản hơn nhiều:
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" ]
}
}
}
}
}
}}
])
Sử dụng $unwind khiến các tài liệu không chuẩn hóa và tạo một bản sao trên mỗi mục nhập mảng một cách hiệu quả. Nếu có thể, bạn nên tránh điều này do chi phí thường rất cao. So sánh việc lọc và đếm các mục nhập mảng trên mỗi tài liệu nhanh hơn nhiều. Như là một $match đơn giản và $group đường ống so với nhiều giai đoạn.