map reduce を使用してデータセットをピボットするのに問題があります。MongoDB のクックブックを参考にしていますが、奇妙なエラーが発生します。以下のコレクションをピボットして、各ユーザーがすべてのレビュー評価のリストを取得できるようにします。
私のコレクションは次のようになります。
{
'type': 'review',
'business_id': (encrypted business id),
'user_id': (encrypted user id),
'stars': (star rating),
'text': (review text),
}
Map 関数 (Python でラップ):
map = Code(""""
function(){
key = {user : this.user_id};
value = {ratings: [this.business_id, this.stars]};
emit(key, value);
}
""")
map 関数は、キーに関連付けられた値の配列を返す必要があります... Reduce 関数 (Python でラップ):
reduce = Code("""
function(key, values){
var result = { value: [] };
temp = [];
for (var i = 0; i < values.length; i++){
temp.push(values[i].ratings);
}
result.value = temp;
return result;
}
""")
ただし、結果は合計よりも1 つ少ない評価を返します。実際、None が返されるユーザーもいますが、これはあり得ません。一部のエントリは次のようになります。
{u'_id': {u'user: u'zwZytzNIayFoQVEG8Xcvxw'}, u'value': [None, [u'e9nN4XxjdHj4qtKCOPQ_vg', 3.0], None, [...]...]
コードの何が原因であるかを特定できません。レビューが 3 件ある場合、すべてのレビューにビジネス ID と評価がドキュメントに含まれています。さらに、ループ条件で 'values.length + 1' を使用すると、何らかの理由で values[i] が壊れます。
編集 1
reduce はそれ自体で複数回呼び出されるという事実を受け入れたので、以下に新しい reducer を示します。これは、[ビジネス、評価、ビジネス、評価] の配列を返します。1 つの巨大な配列の代わりに [ビジネス、評価] 配列を出力する方法はありますか?
function(key, value){
var result = { ratings:[] };
var temp = [];
values.forEach(function(value){
value.ratings.forEach(function(rating){
if(temp.indexof(rating) == -1){
temp.push(rating);
}
});
});
result. rartings = temp;
return result;
}