如何在CouchDB中将对象属性从reduce合并到rereduce函数 [英] How to merge objects attributes from reduce to rereduce function in CouchDB

查看:139
本文介绍了如何在CouchDB中将对象属性从reduce合并到rereduce函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我的JSON架构:

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的文档

What i wanted to do, is to find the average salary for each active title. Active titles are document with "from_date" attribute set to "9999-01-01"

这是我的地图功能

function(doc) {
if (doc.type == 'salaries') {
        var dateSalaries = null;
        dateSalaries = doc.to_date.split("-");
        if(dateSalaries[0].localeCompare("9999") == 0){
            emit(doc.emp_no, ["salary", doc.salary] );
        }
    } else if (doc.type == 'titles') {
        var dateTitles = null;
        dateTitles = doc.to_date.split("-");
        if(dateTitles[0].localeCompare("9999") == 0){
            emit(doc.emp_no, ["title", doc.title]);
        }
    }
}

以下是生成的键值已结对:

Here is the resulting key value pairs emited:

http://i.imgur .com / o1Qxz.png

现在,我想将它减少为单个键值对,输出的值设置为javascript对象,就像这样

Now, i want to reduce it into single key-value pair, with the value outputted is set into javascript object like this

{
    "engineer" : 64342,
    "senior engineer" : 123111,
    "staff" : ...,
    "senior staf" : ...,
    .
    .
    .
}

以下是我计划如何做的事情:首先,在减少步骤,我'我将返回合并来自同一emp_no的属性的对象。然后,在reduce步骤中,我将创建一个新对象,该对象具有基于之前减少的值的属性名称。

Here's how i planned to do it: First, in reduce step, i'm gonna return object that merge properties from the same emp_no. Then, in reduce step, i'm gonna create a new object that has properties name based on reduced value before.

这很难解释,所以这是我的reduce函数:

It's hard to explain, so here is my reduce function:

function(keys, values, rereduce) {
    var i, l, attr, sal, rv = {};
    if (rereduce) {
        for (i = 0, l = values.length; i<l ; ++i) {
            if (values[i].hasOwnProperty('salary')) {
                attr = values[i].title;
                sal = values[i].salary;
                if (rv[attr] instanceof Array) {
                    rv[attr].push(sal);
                } else{
                    rv[attr] = [];
                    rv[attr].push(sal);
                }
            }           
        }

        for (var x in rv) {
            if (rv.hasOwnProperty(x)) {
                var totalSalary = 0;
                for (i = 0, l = values.length; i<l ; i++) {
                    totalSalary += rv[x][i];
                }
                rv[x] = totalSalary / rv[x].length;
            }
        }

    } else {
        for (i = 0, l = values.length; i<l ; i++) {
            switch (values[i][0]) {
                case "title" : rv["title"] = values[i][1]; break;
                case "salary": rv["salary"] = values[i][1]; break;
            }
        }
    }
    return rv;
}

此处的结果值是减值,这是我的预期:
http://i.imgur.com/SnlOU.png

The resulting value here is reduced value, which is what i expected: http://i.imgur.com/SnlOU.png

但是,当我在蒲团中将分组值设置为无时,这不是我想要的:

But, when i set the grouping value to 'none' in futon, it's not what i wanted:

{Senior Engineer: null, Assistant Engineer: null, Technique Leader: null}

可能有人帮我解决这个问题?

Could someone help me to solves this?

推荐答案

你在这里推动CouchDB非常接近它的极限—使用reduce函数执行连接和所有操作。

You're pushing CouchDB pretty close to its limits here — using a reduce function to perform a join and everything.

您的问题来自于CouchDB可能会应用零个,一个或多个重新减少步骤这一事实,但您的代码假定只执行一个重新减少步骤。我怀疑 null 结果来自于最终的rereduce步骤适用于来自reduce步骤的一些结果以及来自rereduce步骤的一些结果。

Your problem comes from the fact that CouchDB may apply zero, one or more rereduce steps, but your code assumes that exactly one rereduce step will be performed. I suspect the null results you get come from the fact that the final rereduce step is applied to some results that come from a reduce step and some results that come from a rereduce step.

这是一个小图。 M是映射步骤,R是缩减步骤,RR是重新缩减步骤。

Here's a small diagram. M is a map step, R is a reduce step, RR is a rereduce step.

[X] [X] [X] [X] [X] [X] [X] [X] [X] [X] 
 |   |   |   |   |   |   |   |   |   | 
(M) (M) (M) (M) (M) (M) (M) (M) (M) (M)
 |   |   |   |   |   |   |   |   |   | 
(==R==) (==R==) (==R==) (==R==) (==R==)
   |       |       |       |       | 
  (== R R ==)     (== R R ==)      | 
       |               |           | 
      (====== R R ======)          | 
               |                   | 
              (======== R R ========)
                         |
                         v
                        [X]

使用CouchDB减少视图时,必须reduce步骤输出的数据格式与rereduce步骤输出的数据格式相同。特别是,这意味着您需要存储(求和,计数)对,而不是存储平均值。

With CouchDB reduce views, it is essential that the data output by your reduce step has the same format as the data output by your rereduce steps. In particular, this means that instead of storing averages, you need to store (sum,count) pairs.

这篇关于如何在CouchDB中将对象属性从reduce合并到rereduce函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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