题
我怎么会去约执行情况的查询所需的页码?
基本上,当第1页被请求,得到第5条。对于第2页,获得下一个5和以上。
我计划要使用这个通过couchdb-蟒蛇模块,但这不应该使任何区别的实施。
解决方案
的 CouchDB指南 有一个良好的讨论的分页,其中包括很多样的代码,在这里: http://guide.couchdb.org/draft/recipes.html#pagination 这里是他们的算法:
- 请求
rows_per_page + 1
行查看 - 显示
rows_per_page
行、储存最后一行作next_startkey
- 作为页信息,保持
startkey
和next_startkey
- 使用
next_*
值创建下一个链接,并利用他人创建以前的链接
注:适当的方式获取的网页在CouchDB是通过指定一个起关键,不是一个起始指数像你想象的。但你怎么知道什么是关键的启动第2页上?聪明的解决方案:"不是请求10行为页,你请求11行,但显示只有10和使用价值,在第11行为startkey为下一页"。
如果你希望有多个文件,这些相同的钥匙,你需要用到 startdocid
除了 startkey
来分正确。其原因是, startkey
独自一人将不再足以独特的识别排。这些参数是无用的,如果你不提供 startkey
.事实上,CouchDB将第一个看看 startkey
参数,那么它会使用的 startdocid
参数,以进一步重新开始的范围如果多个潜在盯着行具有同样的关键,但不同文献身份证。同样的事情 enddocid
.
其他提示
CouchDB HTTP View API 提供了大量有效分页的范围。
最简单的方法是使用startkey
和count
。 Count是CouchDB将为该视图请求返回的最大条目数,这取决于您的设计,startkey是您希望CouchDB启动的位置。当您请求视图时,它还会告诉您有多少条目,允许您计算如果要向用户显示该页面的页数。
因此第一个请求不会指定启动键,只会指定要显示的条目数。然后,您可以记下返回的最后一个条目的键,并将其用作下一页的开始键。在这个简单的表单中,您将获得重叠,其中一个页面的最后一个条目是下一个页面的第一个条目。如果这不可取,那么简单地不显示页面的最后一个条目就是微不足道的。
更简单的方法是使用skip参数计算页面的起始文档,但是应谨慎使用此方法。 skip参数只是导致内部引擎不返回它正在迭代的条目。虽然这给出了期望的行为,但它比按键查找页面的第一个文档慢得多。跳过的文档越多,请求就越慢。
这是我到目前为止所提出的 - 获取所有帖子的ID,然后检索前x个ID的实际项目..
它不是非常有效,但比检索所有帖子更重要,然后扔掉大部分。这就是说,令我惊讶的是,它似乎运行得非常快 - 我运行posthelper.page()
方法100次,大约需要0.5秒。
我不想在实际问题中发布这个,所以它不会影响答案 - 这是代码:
allPostsUuid = """
function(doc) {
if(doc.type == 'post'){
emit(doc._id, null);
}
}
"""
class PostsHelper:
def __init__(self):
server = Server(config.dbhost)
db = server[config.dbname]
return db
def _getPostByUuid(self, uuid):
return self.db.get(uuid)
def page(self, number = 1):
number -= 1 # start at zero offset
start = number * config.perPage
end = start + config.perPage
allUuids = [
x.key for x in self.db.query(allPostsUuid)
]
ret = [
self._getPostByUuid(x) for x in allUuids[start : end]
]
if len(ret) == 0:
raise Error404("Invalid page (%s results)" % (len(allUuids)))
else:
return ret
以下是递归的办法,我发现:
采取两个变量
var lastOffset = 0; var counter = 0;
function someRecursive(lastOffset,counter) {
queryView(db, whereClause).then(result => {
var rows_per_page = 5;
//formula below
var page = Math.floor((lastOffset == 0 ? 0: (result.offset - lastOffset) +
(rows_per_page * counter)) / rows_per_page) + 1;
var skip = page * rows_per_page;
if (somerecursionexitcondition) {
counter = lastOffset == 0 ? lastOffset: counter + 1;
lastOffset =result.offset;
someRecursive(lastOffset, counter).then(result => {
resolve();
});
});
}