我有一个带有时间戳文档的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]
,然后在视图上使用startkey
和endkey
参数来返回文档。这种方法的问题在于它如何扩展。假设我的数据库有两千多年的数千份文件。使用这个视图,我需要迭代整个文档集来发现这个。
我相信this question试图问同样的事情,虽然我不太确定所以我想我会添加一个新问题。此外,就我的有限观点写作技巧而言,就该问题给出的答案并不能避免减少较大文档集的溢出错误。
答案 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"]