创建一个couchdb视图,该视图返回文档集中的唯一值数组

时间:2011-04-02 01:28:35

标签: couchdb

我有一个带有时间戳文档的couchdb数据库,所以给定文档的格式是这样的:

{ id: "uniqueid",
  year: 2011,
  month: 3,
  day: 31,
  foo: "whatever"
  bar: "something else"
}

我想构造一组视图,以便给定的键将返回存在文档的年,月或日值数组。例如,给定视图名称Days,我想要以下视图url

/db/_design/designdoc/_view/Days?key=[2011,3]

返回2011年3月存在文档的所有日期的数组。例如,如果2011年3月有六天的文件有一定数量,那么它可能看起来像:

[1, 2, 5, 15, 27, 31]

类似地,

/db/_design/designdoc/_view/Months?key=2011

如果2011年4月,5月和9月有一些文件,可能看起来像:

[4, 5, 9]

/db/_design/designdoc/_view/Years

将在整个数据库中返回一组年份。如果文件有今年和最后一年,它可能看起来像:

[2010, 2011]

我认为很难编写一个返回数组的reduce函数,因为随着文档数量的增加,你最终会遇到减少溢出错误。我知道这是因为我编写了一个有效的reduce函数,但在我用文档加载后开始抛出reduce overflow错误。

我检查过的一个解决方案是创建一个没有reduce的视图,创建一个数组键[year, month, day],然后在视图上使用startkeyendkey参数来返回文档。这种方法的问题在于它如何扩展。假设我的数据库有两千多年的数千份文件。使用这个视图,我需要迭代整个文档集来发现这个。

我相信this question试图问同样的事情,虽然我不太确定所以我想我会添加一个新问题。此外,就我的有限观点写作技巧而言,就该问题给出的答案并不能避免减少较大文档集的溢出错误。

2 个答案:

答案 0 :(得分:1)

我认为,不仅需要使用地图构建视图,还需要使用reduces构建视图。

答案 1 :(得分:0)

无视最终的扩展问题,有两种解决方案。我将仅考虑几天,因为月和年的答案是相似的。

解决方案1:

查看天数:

图:

function(doc) {
    if (doc.year && doc. month && doc.day) {
        emit([ year, month, day ], 1);
    }
}

减少

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

list listDays:

function(head, req) {
    start({
        "headers": {
            "Content-Type": "text/plain"
        }
    });
    var row;
    var days = new Array();
    while(row = getRow()) {
        days.push(row.key[2]);
    }
    var daysString = json.join(',');
    send('[' + daysString + ']');
}

http电话:

http://couch/db/_design/db/_list/listDays/Days?group=true&group_level=2&startkey=["2011","3"]&endkey=["2011","3Z"]

解决方案2:

查看天数:

图:

function(doc) {
    if (doc.year && doc. month && doc.day) {
        emit([ year, month, day ], null);
    }
}

list listDays:

function(head, req) {
    start({
        "headers": {
            "Content-Type": "text/plain"
        }
    });
    var row;
    var days = new Array();
    while(row = getRow()) {
        if (days.indexOf(row.key[2] == -1) { days.push(row.key[2]); }
    }
    var daysString = json.join(',');
    send('[' + daysString + ']');
}

http电话:

http://couch/db/_design/db/_list/listDays/Days?startkey=["2011","3"]&endkey=["2011","3Z"]