对于使用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