couchdb map /减少按日期过滤的多个键

时间:2014-06-21 00:18:48

标签: arrays date mapreduce couchdb

我有一个带有地图缩小的视图设置。现在这段代码很有用:

function(doc) {
    if (doc.type == 'test'){
        if(doc.trash != 1){
                for (var id in doc.items) { 
                emit([id,doc.items[id].name], 1);
            }
        }
    }
}

function(keys,prices){
    return (keys, sum(prices));
}

我得到一个返回,当使用group参数时,它会很好地压缩所有内容。

我的问题/问题,我想添加第三个密钥....日期,所以我只能减少某些日期的记录。例如:

function(doc) {
    if (doc.type == 'test'){
        if(doc.trash != 1){
                for (var id in doc.items) { 
                emit([date,id,doc.items[id].name], 1);
            }
        }
    }
}

我的问题是,因为日期是在数组的开头,按日期,id等减少组。我知道我使用group_level并且说从数组或前2个键中取第一个键,但这不是无论是因为afaik,group_level在数组中从左向右移动。我可以将日期放在emit数组的末尾,但这也无济于事,因为我需要在我的startkey和endkey的开头有值才能搜索。

以下是数据输出的示例:

{"key":["2012-03-13","356752b8a5f6871f3","Apple"],"value":1},
{"key":["2012-03-20","123752b8a76986857","Pear"],"value":1},
{"key":["2012-04-12","3013531de05871194","Grapefruit"],"value":1},
{"key":["2012-04-12","356752b8a5f6871f3","Apple"],"value":1},

我希望将APPLE添加到一行,这里它首先按日期添加苹果。如果我删除DATE作为数组中的第一个键,我能够成功地添加所有苹果,但是我无法按日期范围搜索。

关于如何实现这一目标的任何想法?

1 个答案:

答案 0 :(得分:5)

如果我正确理解你想做什么,那么你想把日期作为数组的第一个元素,并使用group_level以及start_key和end_key。

EG。 startkey=[1, "someid"] endkey=[1,"someid",{}] group_level=2

将从日期1获取所有项目(显然在这里选择您自己的格式),ID为#34; someid"和任何名字。在名字之前发出id,似乎很有趣,如果没有关于你实际想要完成什么的更多信息,很难建议你的一般数据模型。如果ID是"类型" id意味着许多项共享相同的ID然后这是有道理的。如果ID是每个商品ID唯一,那么它不是。在这种情况下,你想要发出" name"在ID之前...

修改1

根据您的评论,要执行范围日期,请执行以下操作:

startkey=[1] endkey=[5,{}] group_level=2

您将获得从日期1到日期5的所有内容,按ID分组。 applesoranges等。我在一个非常大规模的生产应用程序中使用这种精确的技术。我实际上将日期格式化为格式为yyyymmdd的易于读取的整数,因此20140624将排在最前面。如果我想从一个月初到现在按照我的小组ID分组,我打电话

startkey=[20140601] endkey=[20140624,{}] group_level=2

它完美无缺,据我所知,你正在做什么。我还有第三个关键层"细节"这使我能够为需要它的项目提供更深层次的分组。然后我可以打电话

startkey=[20140601, "someid"] endkey=[20140624, "someid",{}] group_level=3

要深入了解特定ID的详细信息级别,或者只需使用group_level=3的上一个查询,如果我想要每个ID的详细信息。我确信你可以做到这一点 - 我已经使用所描述的技术在生产应用程序中解决了这个确切的问题。

修改2

如果您想对所有苹果进行分组而不考虑日期,那么您需要让苹果成为密钥中的第一个元素。然后,您可以使用group_level=1在所有视图结果中将所有苹果作为一行,并使用group_level=2在日期范围内使用苹果。这里的不同之处在于,您一次只能对单个项目类型执行group_level=2查询。如果你想要两全其美,那么你很遗憾只需要制作2个视图。这就是密钥排序的工作原理......如果您需要两种类型的查询的快速响应时间,日期范围内的所有项目类型,以及未按日期分组的所有特定项目,我相信2个视图是实现这一目标的唯一途径。

注意

需要注意的另一件事是你的减少功能。只要有可能,建议您使用内置的reduce函数高度。它们在erlang中实现,并且与自定义javascript reduce函数相比进行了高度优化。

在您的情况下,只需用此

替换您的reduce功能

_sum

容易嘿?

如果您发布有关您的应用程序,数据模型等的更多信息,那么我很乐意为您的数据库设计提供更多帮助。