ここで使用できるいくつかの異なるアプローチがあります:
-
map/reduceを使用します。これは行わないでください。現時点では、このユースケースでマップリデュース関数を使用するよりも、集計フレームワークを3回実行する方がはるかに高速です。
-
集計を3回実行します。これは最適ではありませんが、時間の制約がない場合は、これが最も簡単なオプションです。集計に<数秒かかる場合は、問題が発生するまで最適化について心配する必要はありません。
-
これが私が考えることができる最良の回避策です。
$group
演算子を使用すると、_id
を作成できます 複数のフィールドで。例えば。{"_id":{"a":"$key1", "b":"$key2", "c":"$key3"}}
。これを行うと、さまざまなキーの既存のすべての組み合わせのグループ化が作成されます。この方法でキーをグループ化し、クライアントの結果を手動で合計することができます。
詳しく説明させてください。図形のコレクションがあるとしましょう。これらの形状には、色、サイズ、および種類(正方形、円など)を含めることができます。マルチキーIDの集計は、次のようになります。
db.shapes.aggregate({$group:{_id:{"f1":"$f1", "f2":"$f2", "f3":"$f3"}, count:{"$sum":1}}})
戻って:
"result" : [
{
"_id" : {
"f1" : "yellow",
"f2" : "medium",
"f3" : "triangle"
},
"count" : 4086
},
{
"_id" : {
"f1" : "red",
"f2" : "small",
"f3" : "triangle"
},
"count" : 4138
},
{
"_id" : {
"f1" : "red",
"f2" : "big",
"f3" : "square"
},
"count" : 4113
},
{
"_id" : {
"f1" : "yellow",
"f2" : "small",
"f3" : "triangle"
},
"count" : 4145
},
{
"_id" : {
"f1" : "red",
"f2" : "small",
"f3" : "square"
},
"count" : 4062
}
...など
次に、大幅に削減されたエントリ数について、クライアント側で結果を合計します。各キーの一意の値の数がドキュメントの総数と比較して十分に少ないと仮定すると、この最後のステップをごくわずかな時間で実行できます。