これを行う最も「パフォーマンスの高い」方法は、 $unwind
をスキップすることです。 全体として、単に $group
カウントする。基本的に「フィルター」配列は$size
を取得します 結果を$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]
]
}
}
}
}}
])
MongoDBの将来のリリースには、$filter
が含まれる予定です。 、これにより、これがはるかに簡単になります:
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" ]
}
}
}
}
}
}}
])
$unwind
を使用する ドキュメントを非正規化し、配列エントリごとにコピーを効果的に作成します。多くの場合極端なコストがかかるため、可能な場合はこれを回避する必要があります。ドキュメントごとの配列エントリのフィルタリングとカウントは、比較するとはるかに高速です。単純な$match
も同様です および$group
多くの段階と比較したパイプライン。