CouchDB、MapReduce:查询时间片



对于使用CouchDB监视应用程序,我需要汇总数据的一个字段(例如,执行已记录的方法所需的时间)。

使用map-reduce对我来说没有问题,但是我只需要总结一个特殊时间片中记录的数据。

示例记录:

{_id: 1, methodID:1, recorded: 100, timeneeded: 10}, 
{_id: 2, methodID:1, recorded: 200, timeneeded: 11}, 
{_id: 3, methodID:2, recorded: 200, timeneeded: 2}, 
{_id: 4, methodID:1, recorded: 300, timeneeded: 6}, 
{_id: 5, methodID:2, recorded: 310, timeneeded: 3}, 
{_id: 6, methodID:1, recorded: 400, timeneeded: 9}

现在我想要得到recorded在200到350范围内并按methodID分组的所有记录的timeneeded的总和。(methodID:1为17,methodID:2为5)

我该怎么做呢?


我现在尝试了一个列表函数,它使用了WickedGrey的想法。查看我的函数:

地图功能:

function(doc) {  
  emit([ doc.recorded], {methodID:doc.methodID, timeneeded:doc.timeneeded}); 
}

列表功能:

"function(head, req) {  
  var combined_values = {};
  var row;   
  while (row = getRow()) {  
      if( row.values.methodID in combined_values)     { 
        combined_values[ row.values.methodID] +=row.values.timeneeded; 
      }        
      else {  
        combined_values[ row.values.methodID] = row.values.timeneeded;    
      } 
  } 
  for(var methodID in combined_values){ 
    send( toJSON({method: methodID, timeneeded:combined_values[methodID]}) );
  }   
}"

现在我有两个问题:1. 我总是以文件的形式得到结果,我的firefox会问我是否要下载它,而不是像查询经典视图那样在浏览器中查看它。2. 据我所知,结果现在是在list函数中动态计算的。我预计这不会很快,因为有数亿条记录……有什么更快的办法吗?

谢谢你的帮助!安迪

在CouchDB中,您不能使用映射键按一组标准进行筛选,而是按另一组标准进行分组。但是,您可以按时间范围过滤键,并使用reduce函数进行分组。试试这样做:

function map(doc) {
    emit(doc.recorded, {doc.methodID: doc.timeneeded});
}
function reduce(key, values, rereduce) {
    var combined_values = {};
    for (var i in values) {
        var totals = values[i];
        for (var methodID in totals) {
            if (methodID in combined_values) {
                combined_values[methodID] += totals[methodID];
            }
            else {
                combined_values[methodID] = totals[methodID];
            }
        }
    }
    return combined_values;
}

这应该允许您指定一个开始/结束键,并且group_level=0应该为您提供一个包含您正在查找的字典的值。

编辑:另外,这个线程可能会感兴趣:

http://couchdb-development.1959287.n2.nabble.com/reduce-limit-error-td2789734.html

它讨论了关闭reduce must收缩消息的选项,并在列表的后面提供了实现相同目标的其他方法:使用列表函数。这可能是一个比我在这里概述的更好的方法。(

function map(doc) {
  if(doc.methodID && doc.recorded && doc.timeneeded) {
    emit([doc.methodID,doc.recorded], doc.timeneeded);
  }
}
//reduce
_sum

相关内容

  • 没有找到相关文章

最新更新