I'm struggling with pivoting my dataset using map reduce. Despite referencing the MongoDB cookbook for guidance, I'm encountering some strange errors. I aim to restructure the provided collection so that each user has a comprehensive list of all review ratings.
Here's how my collection is structured:
{
'type': 'review',
'business_id': (encrypted business id),
'user_id': (encrypted user id),
'stars': (star rating),
'text': (review text),
}
Python-wrapped Map function:
map = Code(""""
function(){
key = {user : this.user_id};
value = {ratings: [this.business_id, this.stars]};
emit(key, value);
}
""")
The map function should output an array of values linked to the key... Python-wrapped Reduce function:
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;
}
""")
However, the results return one less rating than expected. Additionally, some users are receiving 'None' as output, which should not occur. Here are examples of problematic entries:
{u'_id': {u'user: u'zwZytzNIayFoQVEG8Xcvxw'}, u'value': [None, [u'e9nN4XxjdHj4qtKCOPQ_vg', 3.0], None, [...]...]
I'm struggling to identify the underlying issue in my code. When there are 3 reviews, all containing business IDs and ratings in the document, it becomes puzzling. Also, for some reason, using 'values.length + 1' in my loop condition disrupts 'values[i]'.
Edit 1
I've acknowledged that the reducer is repeatedly called on itself, so I've revised my approach. The updated reducer now returns an array of [business, rating, business, rating]. Any suggestions on how to generate [business, rating] arrays instead of one large array?
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;
}