CouchDB意外减少/减少行为

时间:2019-04-24 22:46:08

标签: mapreduce couchdb

我假设我看错了问题,但是我似乎意外地击中了rereduce

我的问题的一个简化示例是学生成绩单

数据(采用表格格式以便于阅读)

Entered     Student  Assig   Grade
2019-02-01  Alice        1    0.80
2019-03-01  Alice        2    0.50
2019-04-01  Alice        2    0.80
2019-04-01  Alice        3    0.80

与数据相关的故事是,爱丽丝是一个好学生,但指导老师却不屑一顾。爱丽丝(Alice)向老师指出,然后老师对成绩报告进行了修改。出于会计原因,可能不会删除条目,但可能会添加更新的条目。

地图:

function(doc){
    var key = [doc.student,doc.assig];
    var val = {
        grade:doc.grade,
        entered: doc.entered
    };
    emit(key,val);
}

减少时有两个目标:

  1. 取得最近输入的成绩
  2. 收集stats的成绩
function(keys,values,rereduce){
    if(rereduce){
        return sum(values);
    }
    else{
        value = values.pop();
        for(var v in values){
            v = values[v];
            if(v.entered > value.entered){
                value = v;
            }
        }
        return value.grade;
    }
}

我申请group=true的那一刻,我希望得到一份关于每项作业的最新成绩的列表。相反,我得到的是所有等级的总和。

Key           Actual   Expected
["Alice",1]     0.8       0.8
["Alice",2]     1.3       0.8
["Alice",3]     0.8       0.8

奇怪的是,进一步减少:

Key           Actual   Expected
["Alice"]       2.4       2.4

我很困惑。我如何迷惑自己?

(CouchDB v2.3)

编辑

好的,所以我知道我怎么做错了(索引溢出),但是现在我想知道如何正确设置...

http://guide.couchdb.org/draft/views.html#reduce

对于group_leve 1和2的行为,我还是很困惑。

1 个答案:

答案 0 :(得分:0)

我怀疑这是我在使用错误的工具来完成工作。当他们有一份工作时,减少CouchDB的最佳工作。

最后使用的解决方案是创建一个update函数,该函数将新成绩简单地添加到现有文档的数组中。

大量基于RTFM时刻:https://docs.couchdb.org/en/stable/ddocs/views/collation.html

Student  Assig   Grades
Alice        1    [{e:'2019-02-01',g:0.80}]
Alice        2    [{e:'2019-04-01',g:0.80},{e:'2019-03-01',g:0.50}]
Alice        3    [{e:'2019-04-01',g:0.80}]

地图更改为...

function(doc){
    var key = [doc.student,doc.assig];
    var val = doc.grades.shift().grade;
    emit(key,val);
}

...并且reduce可以使用内置的reduce函数。

唯一丢失的是对数据的修改不那么明显,但是创建一个视图以对此进行报告很简单:

function(doc){
    for(var val in doc.grades){
        var key = [doc.student,doc.assig,val.entered];
        emit(key,val.grade);
    }
}

现在,用户可以访问更改的详细列表以及汇总结果。

上面的代码未经测试,是一个琐碎的问题示例。从概念上讲,它是正确的;从句法上讲,我希望有问题。