【问题标题】:couchdb map/reduce view: counting only the most recent itemscouchdb map/reduce 视图:只计算最近的项目
【发布时间】:2013-03-10 09:38:10
【问题描述】:

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

{
  _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,{}]

这为我提供了名为 aname 的配置文件的最新文档。

但现在我想计算每个关键字的所有最新文档,并对位置求和。仅使用 map/reduce 来解决这个问题,我无法理解。

我的用户案例是:

  1. 查找每个 profile.user、每个关键字的最新文档
  2. 计算每个关键字的唯一 profile.name 的数量
  3. 按关键字汇总最近文档的位置

我可以让它工作的唯一方法是使用以下列表函数:

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?

谢谢

【问题讨论】:

    标签: mapreduce couchdb


    【解决方案1】:

    有些部分的意思还是有点模糊(比如,什么是“位置”?)。

    但从纯粹的正式角度来看,您的列表似乎在 keyword 上创建了索引,而您的地图在 [profile, keyword, timestamp] 上创建了索引。

    如果您真的需要不同的索引,那么您需要多张地图,每个索引一张。唯一的例外是当您在[a,b,c] 上已有地图时,您可以更改“组级别”并获取另外两个索引:[a,b][a]

    【讨论】:

    • 细节不是特别重要。要点与您所说的完全一样:我需要对个人资料,关键字,时间戳进行索引,以首先获得每个个人资料,每个关键字的最新“位置”。然后,我需要对关键字进行索引以计算和求和位置。一个视图中有两种不同的排序——确定这是 map/reduce 无法完成的事情吗?但是,couchdb list 功能似乎使我能够做到这一点。但是当配置文件的 nr 增加时,我将在遍历视图的所有结果时遇到问题......
    • 问题是您在列表中创建的索引不会被存储。所以性能将是相当次优的。如果您需要良好的性能,请为每个索引创建一个映射。如果你真的需要在同一个资源中混合这些索引,你应该在外部使用 NodeJS 来完成。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-01
    • 1970-01-01
    相关资源
    最近更新 更多