CouchDB中的无状态分页?

时间:2010-06-21 01:50:56

标签: python pagination couchdb

我在与CouchDB分页时看到的大部分研究表明,您需要做的是从您的视图中获取前十个(或多个)项目,然后记录最后一个文档的docid并将其传递给下一个文档页。不幸的是,我可以看到这个方法有一些明显的问题。

  • 这显然使得无法在页面集中跳过(如果有人直接跳到第100页,您必须运行第2-99页的查询,这样您就知道如何加载页面100)。
  • 它要求您在页面之间传递大量状态信息。
  • 正确编码很困难。

不幸的是,my research已经表明,使用skip会使数据集5000个记录或更大的记录显着减速,并且一旦达到任何真正巨大的记录就会严重削弱(转到20000页有10条记录到页面大约需要20秒 - 是的,有些数据集在生产中很大。所以这不是一个真正的选择。

所以,我要问的是,是否有一种有效的方法可以在CouchDB中对查看结果进行分页,从而可以从任意页面获取所有项目? (我正在使用couchdb-python,但希望没有任何与客户相关的内容。)

2 个答案:

答案 0 :(得分:3)

我是CouchDB的新手,但我想我可以提供帮助。我从 CouchDB:The Definitive Guide 中读到以下内容:

  

链接列表样式分页的一个缺点是......跳转到特定页面并不真正有用......如果你真的需要跳转到整个文档范围的页面......你仍然可以维护一个整数值索引作为视图索引,并具有解决分页的混合方法。
- http://books.couchdb.org/relax/receipts/pagination

如果我正确地阅读,那么您的案例中的方法将是:

  1. 将数字序列嵌入到文档集中。
  2. 将该数字序列提取为数字视图索引。
  3. 使用算术计算任意页面的正确开始/结束数字键。
  4. 对于第1步,您需要将“page_seq”之类的内容添加为文档中的字段。关于你如何获得这个数字,我没有具体的建议,我很想知道人们的想法。为了使这个方案有效,它必须为每个新记录增加1,所以RDBMS序列可能已经输出(我熟悉的那些可能会跳过数字)。

    对于第2步,你要编写一个带有这样的地图函数的视图(在Javascript中):

    function(doc):
        emit(doc.page_seq, doc)
    

    对于第3步,您可以编写类似这样的查询(假设page_seq和页面编号序列从1开始):

    results = db.view("name_of_view")
    page_size = ... # say, 20
    page_no = ... # 1 = page 1, 2 = page 2, etc.
    begin = ((page_no - 1) * page_size) + 1
    end = begin + page_size
    my_page = results[begin:end]
    

    然后你可以遍历my_page。

    明显的缺点是page_seq假设您没有过滤视图的数据集,如果您尝试使用任意查询,则会很快遇到麻烦。

    评论/改进欢迎。

答案 1 :(得分:1)

我们通过将CouchDB Lucene用于搜索列表解决了这个问题。 0.6 Snapshot足够稳定你应该尝试一下:

CouchDB Lucene repository