Hi all,
The last couple of days I have been trying to build a view that would act as
a recommender. I have tried all the stuff that I could find/think of, but I
can't find a solution. I hope someone can tell me how I can do it or maybe
tell me that it is just not possible with one map reduce. Below is the
problem description, I hope it is clear enough.
The basic idea is to use co-occurrences of apps attached to a user to
calculate the similarity between apps. This is how the two types of
documents; users and apps, look like:
{ _id: 'user-1', _type: 'user', app_ids: 'app-1', 'app-2' }
{ _id: 'app-1', _type: 'app', user_ids: 'user-1', 'user-2' }
I was hoping the map reduce approach below would work when adding the
include_docs=true option. Unfortunately this doesn't work with a reduce
function. So the remaining problem so far seems to be to obtain the total
app count together with the co-occurrence counts.
//map
function(doc) {
if(doc.type == "user") {
var app_count = doc.app_ids.length;
for(var i = 0; i < app_count; i++) {
for(var j = i + 1; j < app_count; j++) {
emit([doc.app_ids[j], doc.app_ids[i]], [0, 1, 0, {_id:
doc.app_ids[i]}]);
emit([doc.app_ids[i], doc.app_ids[j]], [0, 1, 0, {_id:
doc.app_ids[j]}]);
}
}
}
}
//reduce
function(keys, values, rereduce) {
//output is [similarity, number of co-occurrences, total number, doc]
var output = [0, 0, 0, null];
values.forEach(function(pair) {
output[1] += pair[1];
output[2] = pair[2].user_ids.length;
output[0] = output[1] / output[2];
output[3] = pair[3];
});
return output;
}
Hopefully someone has new insights that can help me a bit further. Thanks.
Jeroen