CouchDB 意外 reduce/rereduce 行为

CouchDB unexpected reduce/rereduce behaviour

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

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

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

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

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

地图:

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 的行为仍然很困惑。

我怀疑是因为我在工作中使用了错误的工具。当他们只有一份工作时,减少在 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);
    }
}

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

上面的代码未经测试,因为它是一个简单的问题示例。从概念上讲,它是正确的;在句法上,我预计会出现问题。