如何获取数据存储查询的第n条记录

1 投票
2 回答
927 浏览
提问于 2025-04-15 11:25

假设我在 GAE 上有一个叫 Foo 的模型,然后我有这样一个查询:

query = Foo.all().order('-key')

我想获取第 n 条记录。有什么最有效的方法可以做到这一点呢?

如果排序的属性不是唯一的,比如下面这个:

query = Foo.all().order('-color')

那么这个解决方案会出问题吗?

补充说明:n > 1000

再补充一下:我想开发一个友好的分页机制,能够显示可用的页面(比如第 1 页、第 2 页……第 185 页),并且在查询字符串中需要使用 "?page=x" 而不是 "?bookmark=XXX"。当 page = x 时,查询的目的是从该页面的第一条记录开始获取数据。

2 个回答

2

关于Query类的文档可以在这里找到:http://code.google.com/appengine/docs/python/datastore/queryclass.html#Query

这个查询类提供了一个叫做fetch的方法,它可以设置限制和偏移量,在你的情况下是1和n。

fetch的运行时间会随着偏移量和限制的增加而线性增长。

所以在你的情况下,优化的唯一方法就是确保你最常访问的记录尽量靠近数组的开头。

你可以使用以下代码:
query.filter('key = ', n)
query.get()

这样可以返回第一个匹配的键为n的记录。

3

其实没有什么高效的方法可以做到这一点,无论是什么数据库管理系统。在任何情况下,你至少得顺序读取索引记录,直到找到第n个,然后再查找对应的数据记录。这大致就是GAE中的fetch(count, offset)所做的事情,不过它有个额外的限制,就是最多只能处理1000条记录。

一个更好的方法是保持一个“书签”,这个书签包含你最后获取的实体的排序字段的值和实体的键。这样,当你想从上次停下的地方继续时,可以把这个字段的值作为查询的下限,然后跳过一些记录,直到找到你最后看到的那条记录或者超过它。

如果你想给用户提供“友好的”页面偏移量,你可以使用memcache来存储一个起始偏移量和书签(排序属性,键)之间的关联。当你生成一个页面时,插入或更新最后一个实体之后的书签。当你获取一个页面时,如果书签存在就用它,否则就得用比较麻烦的方法,通过偏移量进行查询——如果偏移量很高,可能需要进行多次查询。

撰写回答