CouchDB按日期范围和类型求和

时间:2015-06-07 20:33:02

标签: mapreduce couchdb

简单地说,我希望按类型分组的日期范围_sum总计。数据库中的原始文档均为单个日期,包含类型的数据。 (例如,每个文档都会在日期中选择总苹果,橙子和梨。我们要查询在日期范围内挑选的总苹果,橙子和梨。)

“myview”地图发出

emit([date, type], values_array);

我可以查询日期范围

..._view/myview?group=true&group_level=2&startkey=[20150501]&endkey=[20150530,{}]

存在问题。它可以在group_level=1给出每个日期的总和,但我想忘记那时的日期。我想以某种方式重新键入类型,然后求和。

我认为我需要两个相继的观点,但不知道如何做到这一点。

2 个答案:

答案 0 :(得分:1)

试试这个地图功能

emit([type,date], values_array);

键的顺序很重要。如果您想对查询结果进行分组,那么您希望在"最少改变到最多变化的"订购。这是在文档中发出的密钥,它将首先改变组的最小值。然后键将比前一个更改,依此类推。例如,上面的emit函数应该返回输出

["type1",20150501],val of the keys
["type1",20150502],val of the keys
["type1",20150503],val of the keys
["type2",20150502],val of the keys

请注意" type1"三个结果相同,日期变化最大。现在,如果你在视图上?group_level=1,你会得到像

这样的结果
["type1"],val of the keys

这是按" type1"分组的所有键。如果您执行?group_level=2,您将获得按" type1"分组的所有密钥。 日期键。这意味着如果第一个和第二个键都相等,它们将被组合在一起。

在couchdb中进行分组从左到右进行。检查第一个最左边的键以查看它们是否相等,然后检查下一个键,依此类推。所有相等的键组合在一起。

答案 1 :(得分:1)

我在视图上使用列表函数完成了此操作。这是概述:

  • 视图处理选择日期范围(按日期键并使用.../myview?startkey=20150101&endkey=20150130
  • List有一些按类型分组的Javascript。 (作为奖励,你也可以排序)。

My List函数看起来像这样(基于this Q&A关于按类型分组javascript数组):

function (head, req){
         var row;
         var rows = [];
         while(row = getRow()){
                rows.push({
                    "type": row.value.type,
                    "value1": row.value.value1,
                    "value2": row.value.value2      
                });
         };


        var result = rows.reduce(function(res, obj) {
                if (!(obj.type in res)){
                    res.__array.push(res[obj.type] = obj);
                } else {
                    res[obj.symbol].value1 += obj.value1;
                    res[obj.symbol].value2 += obj.value2;
                }
                return res; 
                }, 
                {__array:[]}).__array;

        send(toJSON(result));
    }

之前的查看应该emit将日期作为键,将javascript对象作为值。在此示例中,视图的一行应如下所示:"key":20150101, "value":{"type":"apple", "value1":28, "value2":0}。如果您是Couch的新手,请按照以下方式编写map功能(并且不要使用降低功能,但不要试图使用_sum):

function(doc){
    if (doc.type === "mydoctype"){
        // build array for the day
        var items = [];
        doc.items.forEach(function(item){
            items.push({
                    'type': item.type,
                    'value1': +item.value1,
                    'value2': +item.value2
                   });
             });

        items.forEach(function(item){
            // convert text date "yyyy-mm-dd"
            var x = doc.date.split('-');
            // to numerical date YYYYMMDD
            newformatdate = +(x[0]+x[1]+x[2]);

            emit(newformatdate, item);
        });
    }
}

最后,您的查询将如下所示:

http://localhost:5984/dbname/_design/ddocname/_list/mylistname/myviewname?startkey=20150501&endkey=20150510

我对Javascript和Couch都不熟悉,所以请随意对此代码进行重击。