原始收藏:
{
"_id" : ObjectId('xxxxxxxxxxxxxxxx'),
"userId" : ObjectId('yyyyyyyyyyyyyyyy'),
"urlId" : ObjectId('zzzzzzzzzzzzzzzzzz')
},
{
"_id" : ObjectId('uuuuuuuuuuuuuuuuuu'),
"userId" : ObjectId('aaaaaaaaaaaaaaaa'),
"urlId" : ObjectId('zzzzzzzzzzzzzzzzzz')
}
发射:
emit(this.urlId, {userId: this.userId, visitCount: this.visitCount});
减少
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};
};
所需的MR输出集合:
{
"_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>
}
}
答案 0 :(得分:4)
您想知道每个用户访问您网站上每个网址的次数吗?我想你会想要以不同的方式解决这个问题。
发出网址/用户访问次数:
emit( { urlId: this.urlId, userId: this.userId }, { count: 1 } );
使用reduce计算它们:
r = function( key , values ){
var total = 0;
for ( var i=0; i<values.length; i++ )
total += values[i].count;
return { count : total };
};
然后,如果你真的想要你所说的所需输出,你可以在最后的步骤中做到这一点。但我认为它不能很好地扩展到N个用户。
这是一个不完全符合您既定目标的链接,但在尝试理解这些mongodb mapreduce函数如何工作时,我发现它非常有用:
http://cookbook.mongodb.org/patterns/unique_items_map_reduce/
答案 1 :(得分:0)
对于其他试图在reduce函数中解决此问题的人:
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;
}
reduce函数在MongoDB的上下文中运行,因此您需要了解支持的函数中的内容。