Reputation: 2035
original collection:
{
"_id" : ObjectId('xxxxxxxxxxxxxxxx'),
"userId" : ObjectId('yyyyyyyyyyyyyyyy'),
"urlId" : ObjectId('zzzzzzzzzzzzzzzzzz')
},
{
"_id" : ObjectId('uuuuuuuuuuuuuuuuuu'),
"userId" : ObjectId('aaaaaaaaaaaaaaaa'),
"urlId" : ObjectId('zzzzzzzzzzzzzzzzzz')
}
emit:
emit(this.urlId, {userId: this.userId, visitCount: this.visitCount});
reduce:
function(key, values) {
var visitCount = 0;
var userVC = new Array();
values.forEach(function(doc) {
NOT SURE WHAT TO PUT HERE TO ACHIEVE DESIRED OUTPUT COLLECTION
});
return {urlId: key, userVC: userVC};
};
desired MR output collection:
{
"_id" : ObjectId('zzzzzzzzzzzzzzzzzzzz'),
"value" : {
"urlId" : ObjectId('zzzzzzzzzzzzzzzzzzzz'),
"userVC" : {
ObjectId('yyyyyyyyyyyyyyyy') : <total visit count for this userId on this urlId>,
ObjectId('aaaaaaaaaaaaaaaa') : <total visit count for this userId on this urlId>
}
}
Upvotes: 2
Views: 6282
Reputation: 11031
For anyone else trying to solve this in the reduce function:
function reduce(key, values) {
const result = {
list: [],
...
};
// keep track of reduced records to avoid duplicate list entries
const processed = {
list: [],
...
};
values.forEach((value, index) => {
if (value.listItem && value.listItem.length > 0) {
// our value is an array as MongoDB needs to be strongly typed (same as reduced type)
if (processed.list.indexOf(value.listItem[0].key) === -1) {
result.list = result.list.concat(value.listItem);
}
}
...
});
return result;
}
The reduce function runs in the context of MongoDB so you need to be aware of what goes in the function that is supported.
Upvotes: 0
Reputation: 1753
You want to know how many times each user visited each individual url on your site? I think you will want to solve this differently.
Emit a count of url/user visits:
emit( { urlId: this.urlId, userId: this.userId }, { count: 1 } );
Count them with the reduce:
r = function( key , values ){
var total = 0;
for ( var i=0; i<values.length; i++ )
total += values[i].count;
return { count : total };
};
Then if you really really wanted the desired output you stated, you could do that in a finalize step. But I think it doesn't scale well to N users.
Here is a link that doesn't exactly satisfy your stated goal, but I found very useful when trying to understand how these mongodb mapreduce functions work:
http://cookbook.mongodb.org/patterns/unique_items_map_reduce/
Upvotes: 4