每次创建视图时,在Rereduce函数中合并对象的属性都会导致错误的值 [英] Merging object's attribute in Rereduce function resulted in wrong value each time the view is created

查看:80
本文介绍了每次创建视图时,在Rereduce函数中合并对象的属性都会导致错误的值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是此问题的后续操作如何在CouchDB中将对象属性从reduce到rereduce功能合并

This is follow up from this question How to merge objects attributes from reduce to rereduce function in CouchDB

我一直在关注上一个问题所接受的答案.为了快速查看,这是我的JSON模式:

I've been following the accepted answer from the previous question. For quick review, this is my JSON schema:

{"emp_no": ..,
"salary": ..,
"from_date": ..,
"to_date": ..,
"type" : "salaries"}

{"emp_no": ..,
"title": ..,
"from_date": ..,
"to_date" : ..,
"type" : "titles"}

我想找出每个有效职位的平均工资(用"from_date" ="9999-01-01"表示).由于减少的输出必须与减少的输出相同,因此该值将采用

I want to find out the average salaries for each active titles (denoted by "from_date" = "9999-01-01"). Since the rereduce's output must be the same as the reduce one, the value will be in the form of

{"Title":[sum,count],"Title":[sum,count]}

基于该表格,我将上一个问题的reduce函数更改为:

Based on that form, i changed the reduce function from the previous question into this:

function(keys, values, rereduce) {
    function isArray(o) {
      return Object.prototype.toString.call(o) === '[object Array]';
    }
    var i, l, sal, count, rv = {}, kobj;
    if (rereduce) {
        for (i = 0, l = values.length; i<l ; ++i) {
            if (i === 0) {
                for (kobj in values[i]) {
                    if(values[i].hasOwnProperty(kobj)) {
                        if (isArray(values[i][kobj]) ) {
                            rv[kobj] = values[i][kobj];
                        }
                    }
                }
            } else {
                for (kobj in values[i]) {
                    if(values[i].hasOwnProperty(kobj)) {
                        if (isArray(values[i][kobj])) { 
                            sal = values[i][kobj][0];
                            count = values[i][kobj][1];
                            if ( rv.hasOwnProperty(kobj) && isArray(rv[kobj])) {
                                rv[kobj][0] += sal; 
                                rv[kobj][1] += count; 
                            } else { 
                                rv[kobj] = [sal,count]; 
                            }
                        }
                    }
                }
            }
        }
    } else {
        var t;
        for (i = 0, l = values.length; i<l ; i++) {
            switch (values[i][0]) {
                case "title" :
                    rv[values[i][1]] = null;
                    t = i;
                    break;
                case "salary":
                    rv[values[t][1]] = [values[i][1], 1];
                    break;
                default:
                    rv[values[t][1]] = null;
                    break;
            }
        }
    }
    return rv;
}

以下是折减后的值: http://i.imgur.com/WbmxL.png

这是应用rereduce步骤时的值:

And here is the value when rereduce step is applied :

{Senior Engineer: [417153, 6], Engineer: [171293, 3], Assistant Engineer: [66313, 1], Senior Staff: [248397, 3], Technique Leader: [134222, 2], Staff: [72527, 1]}

让我感到困惑的是,每当创建视图时,减少的值总是在变化!即使我只是在函数末尾添加了注释(//).同样,生成的值总是错误的.这是重新创建视图后的值:

What makes me puzzled, is when each time the view is created, the rereduced value is always change! Even though i just added comment (//) in the end of the function. Also, the value generated is always wrong. Here's the value after the view is recreated:

{Senior Engineer: [540708, 7], Senior Staff: [179364, 2], Engineer: [488026, 6], Staff: [174196, 3], Assistant Engineer: [66313, 1], Technique Leader: [120310, 2]}

我真的很困惑,因为我不知道如何调试以及跟踪CouchDB中MapReduce函数的执行,所以几乎是盲目的.可以使用javascript/MapReduce的专家帮助我指出出什么问题吗?

I'm really confused, and pretty much blind since i don't know how to do debugging and follow the execution of MapReduce function in CouchDB. Could someone expert in javascript / MapReduce help me point out what's wrong?

这是我的薪水和头衔文件.每个文档包含1000个文档,这些文档准备使用HTTP BULK API https://docs插入CouchDB. .google.com/open?id = 0B2o1vMJ7XFKydUxGR3R3NU9QOEE

Here's my salaries and titles document. Each one contain 1000 document that is ready to be inserted into CouchDB with HTTP BULK API https://docs.google.com/open?id=0B2o1vMJ7XFKydUxGR3R3NU9QOEE

推荐答案

您所依赖的是相邻记录.您无法预测Couch将如何拆分传递给reduce函数的一组值.绝对会因同一员工的标题标题和薪金记录之间的拆分而受到呼叫.这意味着在给定的reduce函数调用中,您将拥有标题而不是薪水,反之亦然.

You're relying on adjacent records being present. You can't predict how Couch will split the set of values it passes to your reduce function. You will absolutely get called with the split happening between title and salary records for the same employee. Meaning that in a given invocation of your reduce function you will have a title but not the salary, or vice versa.

我认为没有任何方法可以对您当前的数据结构进行处理.您应该在客户端进行平均计算,或者更改您的文档结构,以便将薪水和职称存储在同一文档中(后者是我的方法).

I don't think there's any way to do what you're trying to with your current data structure. You should do the average calculations on the client side, or change your document structure so that it stores both the salary and the title in the same document (the latter would be my approach).

这篇关于每次创建视图时,在Rereduce函数中合并对象的属性都会导致错误的值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆