查询游标可让应用以便捷的批量方式检索查询结果,因此我们建议使用查询游标,而不是使用整数偏移来实现分页功能。如需详细了解如何为应用设计查询结构,请参阅查询。
查询游标
查询游标让应用以便捷的批量方式检索查询结果,而且不会因查询偏移而产生开销。执行检索操作后,应用会获得一个游标,该游标是一个不透明的 base64 编码字符串,用于标记上次检索的结果的索引位置。应用可以保存此字符串(例如,保存到 Datastore、Memcache、任务队列的任务载荷中,或者以 HTTP GET
或 POST
参数形式嵌入网页中),然后可使用游标作为起点来执行后续检索操作,以从上一次检索结束的位置获取下一批结果。检索还可以指定结束游标,以限制所返回的结果集的范围。
偏移与游标
尽管 Datastore 支持整数偏移,但应该尽量避免使用此类偏移。而应该使用游标。使用偏移只能避免将跳过的实体返回给应用,但这些实体仍会在内部被检索。跳过的实体会影响查询的延迟时间,同时由于检索这些实体需要执行读取操作,您的应用会因此而产生费用。使用游标取代偏移可让您省掉所有这些费用。
查询游标示例
在低层级 API 中,应用可以通过 QueryResultList
、QueryResultIterable
、QueryResultIterator
接口使用游标,这些接口分别由 PreparedQuery
的 asQueryResultList()
、asQueryResultIterable()
、asQueryResultIterator()
方法返回。其中的每个结果对象均提供 getCursor()
方法,该方法又会返回一个 Cursor
对象。应用可通过调用 Cursor
对象的 toWebSafeString()
方法来获取一个表示游标的网页安全字符串,之后可使用静态方法 Cursor.fromWebSafeString()
从该字符串重构游标。
以下示例展示了分页游标的用法:
游标的限制
游标存在如下限制:
- 游标只能由执行原始查询的同一应用使用,并且只能用于继续执行相同查询。为了在后续检索操作中使用游标,您必须准确地重构原始查询,包括相同的实体种类、祖先实体过滤条件、属性过滤条件以及排序顺序。如果没有设置最初生成游标的同一查询,则无法使用游标检索结果。
- 由于
NOT_EQUAL
和IN
运算符是使用多个查询实现的,因此使用它们的查询不支持游标,使用CompositeFilterOperator.or
方法构造的复合查询也不支持游标。 - 对于使用不等性过滤条件或排序顺序来处理多值属性的查询,游标并非总能发挥预期的效果。这种多值属性的去重逻辑不会在多次检索之间持续存在,可能导致多次返回相同结果。
- 新的 App Engine 版本可能会更改内部实现细节,导致依赖于这些细节的游标失效。如果应用尝试使用不再有效的游标,则 Datastore 会引发
IllegalArgumentException
(低层级 API)、JDOFatalUserException
(JDO) 或PersistenceException
(JPA) 异常。
游标和数据更新
游标的位置是指结果列表中上次返回的结果之后的位置。游标不是列表中的相对位置(它不是偏移量),而是 Datastore 在开始对结果进行索引扫描时可以跳转到的标记。如果查询的结果在两次使用游标之间发生了变化,则查询只会注意位于游标之后的结果中发生的变化。如果一个新结果出现在查询的游标位置之前,则在获取游标后的结果时不会返回该结果。同样,如果某个不再是查询结果的实体出现在游标之前,则出现在游标后的结果也不会变化。如果从结果集中移除了上次返回的结果,则游标仍会知道如何定位下一个结果。
检索查询结果时,您可以同时使用开始游标和结束游标,以从 Datastore 返回一组连续的结果。使用开始游标和结束游标检索结果时,结果大小不一定会与生成游标时的大小相同。在生成游标与在查询中使用游标这两个时间点之间,可以在 Datastore 中添加实体或者从中删除实体。
后续步骤
- 了解如何指定查询返回的内容并进一步控制查询结果。
- 了解 Datastore 查询的常见限制。
- 了解数据一致性以及它如何与 Datastore 上不同类型的查询搭配使用。
- 了解 Datastore 查询的基本语法和结构。