CouchDB,MapReduce:查询时间片

CouchDB,MapReduce:查询时间片,couchdb,mapreduce,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:

对于使用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}
现在,我只想得到所有记录的
timeneeded
的总和,这些记录的
记录范围为200到350,并按
methodID
进行分组。(对于
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]}) );
  }   
}"
列表功能:

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.据我所知,结果现在是在列表函数中动态计算的。我希望这不会太快,因为有上亿张唱片。。。有没有办法让它更快

谢谢你的帮助!
andy

在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时,应该会得到一个包含您正在查找的字典的值

编辑:此外,此线程可能会引起兴趣:


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

谢谢你的回答。(为了帮助阅读本文的人,你忘记了reduce函数中的return语句,据我所知,{doc.methodID:doc.timeneeded}语句不可能是那样的。我现在用以下方法:var obj=new Object();obj[doc.methodID]=doc.timeneeded;然后发出obj。再次感谢!再次感谢我…我现在遇到了一个问题,couchdb警告我“减少产出必须更快地收缩”。有没有一种方法可以像我得到Wickedgedrey的答案那样,以同样的方式得到结果,但让它迅速收缩?(他的建议的输出真的非常适合我的需要…).据我所知,问题在于他的解决方案给了我一行数据,而couchdb更喜欢将数据放在不同的行中…对于减少错误,很抱歉!这是关于“必须收缩”的原始线程错误:Hello Wickedrey;我还发现了线程…我禁用了检查,但现在我遇到了一个问题,视图生成需要更多的时间…它甚至占用了很多资源,在视图生成期间写入失败(我让视图在大约300条新记录之后生成)嗨,maybee,我错了,但是你的map函数不是为一个特殊的时间片硬编码的吗?因为我需要能够更改时间片。例如,我想要过去三天的数据…(临时视图不能处理大约10亿行…)我不知道给出的范围只是一个示例。如果您希望能够按范围进行查询,请使用组合键和范围查询。我编辑了上面的内容,以使用[doc.methodID,doc.recorded]键而不是doc.methodID。我也想到了这个解决方案。但现在我有一个问题,如果我想查询给定时间段内所有methodID的数据,我需要查询每个methodID的视图。一个查询很快,但我至少要做2000个。这就是为什么我要寻找一个不同的解决方案。很抱歉,我没有更新我的question.Then
emit([doc.recorded,doc.methodID],doc.timeneeded);
并使用一个doc.methodID键和一个值的总和(doc.timeneeded),使用所需的doc.recorded进行范围查询,但所有doc.methodID.Hi,我尝试了您的想法,但现在我记得为什么以前不使用这种方法…如果我构建一个键的话[doc.recorded,doc.methodID],我有一个问题,几乎没有任何东西会减少。因此,我会得到一个非常长的值列表,每次记录我的数据时(大约每秒)都会有一个值。我认为让客户机做“休息”不是一个好主意aka.工作的主要部分…我错过了什么吗?或者有人有任何其他想法吗?非常感谢!在您编辑之后,我对您的场景不太清楚。您给出示例记录,然后继续使用那些文档中没有的字段。@MetaThis我很抱歉这个错误,我的应用程序中的名称发生了一些更改,但为了保持一致,我编辑了我的pos我在这个列表中使用了TyMes。我在我的列表功能中修复了bug并更新了我的文章。安迪,你明白了吗?我很好奇你的解决方案是什么。