mongodb mapreduce - 在reduce中构建一个数组或对象?

时间:2011-01-04 22:11:52

标签: mongodb mapreduce

原始收藏:

{ 
"_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>
       }
}

2 个答案:

答案 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的上下文中运行,因此您需要了解支持的函数中的内容。