集約フレームワークで説明しているタイプの計算を実行することはできません。そうではありません $unwind
がないため 非配列のメソッド。 person:valueオブジェクトが配列内のドキュメントであったとしても、$unwind
役に立たないでしょう。
「groupby」機能(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の拡張リクエストがあります。これは、値をキーに投影したり、その逆を行ったりする機能です。その間、常にmap/reduceがあります。
[*]すべての一意のキーを知っている場合(これと同様の方法ですべての一意のキーを見つけることができます)、これを行うには複雑な方法がありますが、すべてのキーを知っている場合は、一連のクエリを実行することもできます。 form db.articles.find({"ratings.user1":{$exists:true}},{_id:0,"ratings.user1":1})
すべての評価を返すuserXごとに、集計フレームワークで必要となる非常に複雑な予測を行うのではなく、簡単に合計して平均化できます。