Couchdb map/reduce视图:只统计最近的项



我有以下文件。关键字的时间戳位置。

{
  _id: willem-aap-1234,
  keyword:aap,
  position: 10,
  profile: { name: willem },
  created_at: 1234
},
{
  _id: willem-aap-2345,
  keyword:aap,
  profile: { name: willem },
  created_at: 2345
},
{
  _id: oliver-aap-1235,
  keyword:aap,
  profile: { name: oliver },
  created_at: 1235
},
{
  _id: oliver-aap-2346,
  keyword:aap,
  profile: { name: oliver },
  created_at: 2346
}

查找profile.name中最近的关键字:

map: function(doc) {
if(doc.profile)
    emit(
        [doc.profile.name, doc.keyword, doc.created_at], 
        { keyword : doc.keyword, position : doc.position, created_at: doc.created_at }
    );
}
reduce: function(keys, values, rered) {
  var r = values[0];
  for (var i=1; i<values.length; i++)
    if (r.created_at < values[i].created_at)
      r = values[i];
  return r;
}

然后用

查询数据库
reduce : true,
group_level : 2,
startkey : [aname],
endkey : [aname,{}]

这给了我名称为name的概要文件的最新文档。

但是现在我想计算每个关键字最近的所有文档,并求和位置。如果只使用map/reduce,我无法理解这个问题。

我的用户案例是:

  1. 查找每个配置文件的最新文档。用户,每个关键字
  2. 计算每个关键字的唯一profile.name的个数
  3. 每个关键字
  4. 对最近文件的位置求和

我能使它工作的唯一方法是使用下面的列表函数:

function(head, req) {
  var row;
  var counts = {};
  while (row = getRow()) {
    var v = row.value;
    var k = v.keyword;
    if (v.position) {
      if (!counts[k])
        counts[k] = { 
          position : 0,
          count : 0
        }
      counts[k].position += v.position;
      counts[k].count++;
    }
  }
  return JSON.stringify(counts);
}

谁能想到一个更好的方法来做到这一点,只使用map/reduce ?

谢谢

有些部分的含义还是有点模糊(例如,什么是"position"?)

但是从纯形式的角度来看,似乎你的列表在keyword上创建了一个索引,而你的映射在[profile, keyword, timestamp]上创建了一个索引。

如果你真的需要不同的索引,那么你需要几个映射,每个索引一个。唯一的例外是当你已经有了[a,b,c]的地图,你可以改变"组级别",得到另外两个索引:[a,b][a]

最新更新