【问题标题】:CouchDB sum by date range and typeCouchDB 按日期范围和类型求和
【发布时间】:2015-06-07 20:33:01
【问题描述】:

简单地说,我想_sum 在按类型分组的日期范围内的总数。数据库中的原始文档均针对单个日期,包含按 type 分类的数据。 (例如,每个文档都有在某个日期采摘的苹果、橙子和梨的总数。我们要查询在某个日期范围内采摘的苹果、橙子和梨的总数。)

“myview”地图发送出去

emit([date, type], values_array);

我可以查询日期范围为

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

这就是问题所在。它可以在group_level=1 处为每个日期提供一个总和,但我想忘记那个时候的日期。我想以某种方式重新键入 type 然后求和。

我认为我需要连续两个视图,但不知道该怎么做。

【问题讨论】:

    标签: mapreduce couchdb


    【解决方案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 中的分组从左到右进行。首先检查最左边的键以查看它们是否相等,然后检查下一个键,依此类推。所有相等的键组合在一起。

    【讨论】:

    • 全部正确,但我认为 CouchDB 不能从第二个键中选择日期范围。在按类型减少之前,我不知何故需要排除的日期根本不出现。
    • 您的意思是要根据类型和日期范围进行过滤,但要按类型分组。如果是这样,您可以通过 start 和 endkey 参数排除键。就像你在你的问题中所做的那样。 startkey=["type1",start_date_range]&endkey=["type1",end_date_range]&reduce=true&group_level=1。还是您在寻找其他东西?
    • 是的,但适用于所有类型。我理解为什么 CouchDB 不能这样做,因为它只选择连续的范围。请参阅 couch-db 用户邮件列表中的 markmail.org/thread/4gd3734dencrqwoj。那家伙暗示你可以用“第二种观点”来做到这一点。
    • 我赞成这一点,因为它很好、清楚地说明了在尝试按索引范围内按类型分组时遇到的问题。
    • 谢谢。很高兴你发现它有用:)
    【解决方案2】:

    我在视图上使用 list 函数 完成了这项工作。以下是概述:

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

    我的 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));
        }
    

    前面的View应该emit日期作为key,javascript对象作为value。在此示例中,视图的一行应如下所示:"key":20150101, "value":{"type":"apple", "value1":28, "value2":0}。如果您是 Couch 的新手,以下是您编写 map 函数的方法(不要使用 reduce,但您可能会想 _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 都有些陌生,所以请随意尝试一下这段代码。

    【讨论】:

    • 我忘记了列表!如果您使用列表函数,则无需发出如此大的值。只需使用include_docs=true 参数。使用include_docs=true 查询类似emit(doc.date) 的发射将获得相同的结果,并具有更小的视图索引的附加优势。该文档可通过row[index].doc 访问。使用log() 在控制台上打印内容以帮助您调试。希望它有所帮助:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-11
    • 1970-01-01
    • 2018-08-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多