如何获取数据存储查询的第 n 条记录
假设我在 GAE 中有模型 Foo 和以下查询:
query = Foo.all().order('-key')
我想获取第 n 条记录。 实现这一目标最有效的方法是什么?
如果 ordering 属性不唯一,解决方案是否会中断,如下所示:
query = Foo.all().order('-color')
edit: n > 1000
edit 2:我想开发一种友好的分页机制,显示可用页面(例如第1页,第2页,...第185页),并需要在查询字符串中使用“?page = x”,而不是“?书签=XXX”。 当page = x时,查询将从该页的第一条记录开始获取记录。
Suppose that I have the model Foo in GAE and this query:
query = Foo.all().order('-key')
I want to get the n-th record. What is the most efficient way to achieve that?
Will the solution break if the ordering property is not unique, such as the one below:
query = Foo.all().order('-color')
edit: n > 1000
edit 2: I want to develop a friendly paging mechanism that shows pages available (such as Page 1, Page 2, ... Page 185) and requires a "?page=x" in the query string, instead of a "?bookmark=XXX". When page = x, the query is to fetch the records beginning from the first record of that page.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
在任何 DBMS 中都没有有效的方法来做到这一点。 在每种情况下,您至少必须顺序读取索引记录,直到找到第 n 条,然后查找相应的数据记录。 这或多或少与 GAE 中的 fetch(count, offset) 功能相同,但附加了 1000 条记录的限制。
更好的方法是保留一个“书签”,其中包含您为检索到的最后一个实体订购的字段的值以及该实体的键。 然后,当您想从上次停下的地方继续时,可以将字段的值添加为不等式查询的下限,并跳过记录,直到匹配或超过您看到的最后一个记录。
如果您想为用户提供“友好”的页面偏移量,您可以做的是使用 memcache 来存储起始偏移量和书签(order_property,key)元组之间的关联。 生成页面时,插入或更新上一页后面实体的书签。 当您获取页面时,使用书签(如果存在),或者通过使用偏移量进行查询来以困难的方式生成它 - 如果偏移量足够高,则可能会进行多个查询。
There is no efficient way to do this - in any DBMS. In every case, you have to at least read sequentially through the index records until you find the nth one, then look up the corresponding data record. This is more or less what fetch(count, offset) does in GAE, with the additional limitation of 1000 records.
A better approach to this is to keep a 'bookmark', consisting of the value of the field you're ordering on for the last entity you retrieved, and the entity's key. Then, when you want to continue from where you left off, you can add the field's value as the lower bound of an inequality query, and skip records until you match or exceed the last one you saw.
If you want to provide 'friendly' page offsets to users, what you can do is to use memcache to store an association between a start offset and a bookmark (order_property, key) tuple. When you generate a page, insert or update the bookmark for the entity following the last one. When you fetch a page, use the bookmark if it exists, or generate it the hard way, by doing queries with offsets - potentially multiple queries if the offset is high enough.
查询类的文档可以在以下位置找到:
http://code.google.com/appengine/docs/ python/datastore/queryclass.html#Query
查询类提供获取限制和偏移量
在您的情况下 1 和 n
提取的运行时间随着偏移量+限制线性增长
,因此在您的情况下优化的唯一方法是确保您想要的记录
最常访问的位置靠近数组的开头。
你可以使用
查询.filter('key = ', n)
query.get()
将返回键为 n 的第一个匹配项
Documentation for the Query class can be found at:
http://code.google.com/appengine/docs/python/datastore/queryclass.html#Query
The query class provides fetch witch takes a limit and a offset
in your case 1 and n
The running time of the fetch grows linearly with the offset + the limit
so the only way to optimize in your case would be to make sure that the records you want
to access most often are closer to the beginning of the array.
You could use
query.filter('key = ', n)
query.get()
which would return the first match with a key of n