我在CouchDB中有几个文档,其中包含日期和路径。我想要一个视图,我可以通过路径搜索(可能使用startkey和endkey),对于该路径,我希望视图返回的文档,其中日期是最新的。
一个关于我的数据看起来如何的小例子
{
"path": "abc",
"created_at": "2011-12-03T18:23:49.058Z"
}
{
"path": "abc",
"created_at": "2011-12-03T11:32:42.123Z"
}
{
"path": "cde",
"created_at": "2011-12-06T15:52:34.523Z"
}
我的当前地图函数
function(doc) {
var pathArr = doc.path.split(//|\/);
pathArr.splice(0,1);
emit(pathArr, doc);
}
我试图创建一个reduce函数
function(keys, values) {
var currTime = -Infinity;
var retDoc;
for (var i = 0, v; v = values[i]; i++) {
var dateInMs = new Date(v.created_at).getTime();
//if this doc has a later than than previously latest date found
if(dateInMs >= currTime)
{
currTime = dateInMs;
retDoc = v;
}
}
return retDoc;
}
这会导致错误
{"error":"reduce_overflow_error","message":"Reduce output must shrink more rapidly: Current output: ..."}
我在权威指南中读到,发生错误是因为你不应该从reduce函数返回完整的文档。还有其他解决办法吗?
我很感激我能得到的所有帮助。编辑:我只是想到了一个丑陋的解决方案,让reduce函数返回文档的_id,然后通过第二个请求获取文档。你觉得这个解决方案怎么样?如果你能找到一个好的解决方案,我将非常高兴。
我找到了一个解决方案,如果有人遇到类似的情况,我想把它贴在这里会很好。
解决方案实际上很简单,我只是将pathArray作为一个嵌套数组添加到键。这样我就可以查询文件的路径,并且只得到最新的版本。
这是我的新地图函数:
function(doc) {
if(doc.doctype === "file")
{
var pathArr = doc.guipath.split(//|\/);
pathArr.splice(0,1);
emit([pathArr,doc.created_at], doc);
}
}
我不使用reduce函数
通过添加以下(或类似的)参数来查询该视图:
?startkey=[["haha","file.ext"],{}]&endkey=[["haha","file.ext"]]&descending=true&limit=1
这样我就可以确保我只得到最新的