集計フレームワークで説明しているタイプの計算を実行することはできません。これは、配列以外のメソッドがないためではありません。$unwind
person:value オブジェクトが配列内のドキュメントであったとしても、$unwind
役に立ちません。
"group by" 機能 (MongoDB であろうとリレーショナル データベースであろうと) は、フィールドまたは列の値に対して実行されます。フィールドの値によってグループ化し、別のフィールドの値に基づいて合計/平均などを行います。
簡単な例は、あなたが提案したものの変形であり、例の記事コレクションに評価フィールドが追加されましたが、ユーザーから評価へのマップとしてではなく、次のような配列として:
{ title : title of article", ...
ratings: [
{ voter: "user1", score: 5 },
{ voter: "user2", score: 8 },
{ voter: "user3", score: 7 }
]
}
これを次のように集約できます。
[ {$unwind: "$ratings"},
{$group : {_id : "$ratings.voter", averageScore: {$avg:"$ratings.score"} } }
]
しかし、あなたが説明したように構成されたこの例は、次のようになります。
{ title : title of article", ...
ratings: {
user1: 5,
user2: 8,
user3: 7
}
}
またはこれさえ:
{ title : title of article", ...
ratings: [
{ user1: 5 },
{ user2: 8 },
{ user3: 7 }
]
}
これができたとしても$unwind
、ここで集計することは何もありません。考えられるすべてのキー (ユーザー) の完全なリストを把握していない限り、これで多くのことを行うことはできません。[*]
あなたが持っているものに類似したリレーショナルDBスキーマは次のようになります:
CREATE TABLE T (
user1: integer,
user2: integer,
user3: integer
...
);
それは行われることではなく、代わりに次のようにします。
CREATE TABLE T (
username: varchar(32),
score: integer
);
次に、SQL を使用して集計します。
select username, avg(score) from T group by username;
将来的に集計フレームワークでこれを行うことができるようにする可能性のある MongoDB の拡張要求があります。一方、マップ/リデュースは常にあります。
[*] すべての一意のキーを知っている場合、これを行うには複雑な方法があります (これと同様の方法ですべての一意のキーを見つけることができます)。ただし、すべてのキーを知っている場合は、集計フレームワークが必要とする非常に複雑なdb.articles.find({"ratings.user1":{$exists:true}},{_id:0,"ratings.user1":1})
予測を行うのではなく、単純にそれらを合計して平均することができます。