CouchDB分页按日期排序,由id查询

时间:2010-06-27 20:18:24

标签: couchdb

我想使用CouchDB视图API在应用程序级别创建分页。分页使用游标,因此给定游标,我将查询视图,以给定游标作为开始键开始的n+1文档,并将n结果输出为页面并提供n+1结果行作为下一页的光标。

只要视图键也是我的视图行的键,这个效果很好。现在这次我的所有文档都有一个日期字段,我将它们作为地图键发出,因为我想通过日期排序。但是,我不能像以前那样使用我的游标了。

我认为这就是视图API也提供startkey_docid来提交这样的游标文档ID的原因,但这显然不是真的。看起来这个值只适用于每个键有几个相等的行。

因此,简而言之:我想要一个按日期排序的视图,但是基于文档ID的游标。我怎么能这样做?

提前致谢

Simplified view

function map(doc)
{
    emit(doc.date, {_id: doc._id});
}


Simplified view result:

{
"rows":[
    {"id":"123","key":"2010-06-26T01:28:13.555Z", value:{...}},
    {"id":"234","key":"2010-06-22T12:21:23.123Z", value:{...}},
    {"id":"987","key":"2010-06-16T13:48:43.321Z", value:{...}},
    {"id":"103","key":"2010-05-01T17:38:31.123Z", value:{...}},
    {"id":"645","key":"2009-07-21T21:21:13.345Z", value:{...}}
]
}

Application-level query with cursor 234, page size 3 should return:
    234, 987, 103

那么如何将其映射到视图?

1 个答案:

答案 0 :(得分:1)

为什么你想要基于docid的游标?

Map Reduce会创建单维索引,因此任何非键遍历都会很昂贵。但是,我认为你可以做你想做的事,而不需要同时遍历2个索引。

例如,请参阅此处我如何通过具有特定标记的帖子进行分页:

Sofa's CouchApp tag pagination

又名

http://jchris.couchone.com/sofa/_design/sofa/_list/index/tags?descending=true&reduce=false&limit=10&startkey=[%22life%22%2C {}]&安培; endkey = [%22life%22]

该视图中的键看起来像[“tag”,“2008/10/25 04:49:10 +0000”],因此您可以按标签和标签内的时间分页。

<强>被修改

哈!我刚刚意识到你要做的事情。它非常简单。

忘记所有关于docids的事情,无论如何它们应该是随机的而且与任何事情无关,所以忘记docs甚至有一秒钟的id。

你说“使用游标234的应用程序级查询,页面大小3应该返回:     234,987,103“

你的光标不应该是234.它应该是关键词“2010-06-22T12:21:23.123Z”。

因此,实际上您使用最后一行结果的键作为下一个查询的开始键。例如,startkey =“”2010-06-22T12:21:23.123Z“”&amp; limit = 3,然后对于您呈现的每个页面,链接到新的启动键是最后返回的键的查询。

奖励:根据我刚刚描述的内容,您将第2页的最后一行作为第3页的第一行。要解决此问题,请在查询中添加skip = 1。

奖金奖励:好的,当我在视图中有超过3个文档发送到同一个键时怎么办?然后最后一个键将始终与第一个键相同,因此如果不扩展limit参数,则无法进行分页。除非......你使用startkey_docid(并设置它执行最后一行的id)。这是你应该使用startkey_docid的唯一时间。