Los cursores de consulta permiten a una aplicación obtener los resultados de una consulta en lotes cómodos y se recomiendan en lugar de usar desplazamientos de enteros para la paginación. Consulta Consultas para obtener más información sobre cómo estructurar las consultas de tu aplicación.
Cursores de consultas
Los cursores de consulta permiten que una aplicación recupere los resultados de una consulta en lotes cómodos sin incurrir en la sobrecarga de un desplazamiento de consulta. Después de realizar una operación de recuperación, la aplicación puede obtener un cursor, que es una cadena opaca codificada en base64 que marca la posición del índice del último resultado recuperado. La aplicación puede guardar esta cadena, por ejemplo, en Datastore, en Memcache, en una carga útil de una tarea de cola de tareas o insertada en una página web como parámetro HTTP GET
o POST
. Después, puede usar el cursor como punto de partida de una operación de recuperación posterior para obtener el siguiente lote de resultados desde el punto en el que finalizó la recuperación anterior. Una recuperación también puede especificar un cursor final para limitar el alcance del conjunto de resultados devuelto.
Desplazamientos frente a cursores
Aunque Datastore admite desplazamientos de números enteros, no se recomienda usarlos. En su lugar, usa cursores. Si usas un desplazamiento, solo evitarás que se devuelvan las entidades omitidas a tu aplicación, pero estas entidades se seguirán obteniendo internamente. Las entidades omitidas afectan a la latencia de la consulta y se te factura por las operaciones de lectura necesarias para recuperarlas. Si utilizas cursores en lugar de desplazamientos, puedes evitar todos estos costes.
Ejemplo de cursor de consulta
En la API de nivel bajo, la aplicación puede usar cursores a través de las interfaces
QueryResultList
,
QueryResultIterable
y
QueryResultIterator
que devuelven los métodos
PreparedQuery
asQueryResultList()
,
asQueryResultIterable()
y
asQueryResultIterator()
,
respectivamente. Cada uno de estos objetos de resultado proporciona un método getCursor()
, que a su vez devuelve un objeto Cursor
. La aplicación puede obtener una cadena segura para la Web que represente el cursor llamando al método toWebSafeString()
del objeto Cursor
y, más adelante, puede usar el método estático Cursor.fromWebSafeString()
para reconstituir el cursor a partir de la cadena.
En el siguiente ejemplo se muestra el uso de cursores para la paginación:
Limitaciones de los cursores
Los cursores están sujetos a las siguientes limitaciones:
- Un cursor solo puede utilizarlo la misma aplicación que realizó la consulta original y solo para continuar la misma consulta. Para usar el cursor en una operación de recuperación posterior, debe reconstituir la consulta original exactamente, incluidos el mismo tipo de entidad, el filtro de ancestro, los filtros de propiedad y los órdenes de clasificación. No es posible obtener resultados mediante un cursor sin configurar la misma consulta a partir de la que se generó originalmente.
- Como los operadores
NOT_EQUAL
yIN
se implementan con varias consultas, las consultas que los usan no admiten cursores, ni tampoco las consultas compuestas creadas con el métodoCompositeFilterOperator.or
. - Los cursores no siempre funcionan como se espera con una consulta que usa un filtro de desigualdad o un orden de clasificación en una propiedad con varios valores. La lógica de desduplicación de estas propiedades de varios valores no se mantiene entre las recuperaciones, lo que puede provocar que se devuelva el mismo resultado más de una vez.
- Las nuevas versiones de App Engine pueden cambiar los detalles de implementación internos, lo que invalida los cursores que dependen de ellos. Si una aplicación intenta usar un cursor que ya no es válido, Datastore genera un error
IllegalArgumentException
(API de nivel inferior),JDOFatalUserException
(JDO) oPersistenceException
(JPA).
Cursores y actualizaciones de datos
La posición del cursor se define como la ubicación en la lista de resultados después del último resultado devuelto. Un cursor no es una posición relativa en la lista (no es un desplazamiento), sino un marcador al que Datastore puede saltar al iniciar un análisis de índice para obtener resultados. Si los resultados de una consulta cambian entre usos de un cursor, la consulta solo detecta los cambios que se producen en los resultados después del cursor. Si aparece un nuevo resultado antes de la posición del cursor de la consulta, no se devolverá cuando se obtengan los resultados posteriores al cursor. Del mismo modo, si una entidad deja de ser un resultado de una consulta, pero había aparecido antes del cursor, los resultados que aparecen después del cursor no cambian. Si se elimina del conjunto de resultados el último resultado devuelto, el cursor sigue sabiendo cómo localizar el siguiente resultado.
Al recuperar los resultados de una consulta, puede usar tanto un cursor de inicio como un cursor de finalización para devolver un grupo continuo de resultados de Datastore. Cuando se usan cursores de inicio y de finalización para obtener los resultados, no se garantiza que el tamaño de los resultados sea el mismo que cuando se generaron los cursores. Es posible que se añadan o eliminen entidades de Datastore entre el momento en que se generan los cursores y el momento en que se usan en una consulta.
Siguientes pasos
- Consulta cómo especificar lo que devuelve una consulta y controlar aún más los resultados de las consultas.
- Consulta las restricciones habituales de las consultas en Datastore.
- Consulta información sobre la coherencia de los datos y cómo funciona con los diferentes tipos de consultas en Datastore.
- Consulta la sintaxis y la estructura básicas de las consultas de Datastore.