query pagination couchdb

pagination - query - Paginación en CouchDB?



pouchdb query (3)

¿Cómo voy a implementar las consultas requeridas para la paginación?

Básicamente, cuando se solicita la página 1, obtenga las primeras 5 entradas. Para la página 2, obtenga los próximos 5 y así sucesivamente.

Planeo usar esto a través del módulo couchdb-python, pero eso no debería hacer ninguna diferencia en la implementación.


Esto es lo que se me ocurrió hasta ahora: obtener las identificaciones de todas las publicaciones y luego recuperar los elementos reales para la primera x número de identificaciones.

No es terriblemente eficiente, pero más que recuperar todas las publicaciones, y luego descartar la mayor parte. Dicho esto, para mi sorpresa, parecía funcionar bastante rápido: ejecuté el método posthelper.page() 100 veces y me llevó unos 0,5 segundos.

No quería publicar esto en la pregunta real, por lo que no influiría tanto en las respuestas: aquí está el código:

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


La API de vista HTTP de CouchDB ofrece un amplio alcance para hacer paginación de manera eficiente.

El método más simple usaría startkey y count . Count es la cantidad máxima de entradas que CouchDB devolverá para esa solicitud de vista, algo que depende de su diseño, y la tecla de inicio es donde desea que inicie CouchDB. Cuando solicite la vista, también le indicará cuántas entradas hay, lo que le permitirá calcular cuántas páginas habrá si desea mostrarlas a los usuarios.

Por lo tanto, la primera solicitud no especificaría una clave de inicio, solo el recuento de la cantidad de entradas que desea mostrar. Luego puede anotar la clave de la última entrada devuelta y usarla como la tecla de inicio para la página siguiente. En esta forma simple, obtendrá una superposición, donde la última entrada de una página es la primera de la siguiente. Si esto no es deseable, es trivial simplemente no mostrar la última entrada de la página.

Un método más simple de hacer esto es usar el parámetro omitir para calcular el documento de inicio de la página, sin embargo, este método debe usarse con precaución. El parámetro de omisión simplemente hace que el motor interno no devuelva las entradas sobre las que se está iterando. Si bien esto proporciona el comportamiento deseado, es mucho más lento que encontrar el primer documento para la página por clave. Cuantos más documentos se salten, más lenta será la solicitud.


La Guía de CouchDB contiene una buena explicación de la paginación, incluidos muchos ejemplos de código, aquí: http://guide.couchdb.org/draft/recipes.html#pagination Aquí está su algoritmo:

  • Solicite rows_per_page + 1 filas de la vista
  • Mostrar rows_per_page rows, almacenar la última fila como next_startkey
  • Como información de la página, mantenga la startkey y la next_startkey startkey next_startkey
  • Use los valores next_* para crear el siguiente enlace y use los otros para crear el enlace anterior

Nota: la forma correcta de buscar páginas en CouchDB es especificando una clave de inicio, no un índice de inicio como podría pensar. ¿Pero cómo sabes en qué tecla comenzar la segunda página? La solución inteligente: "En lugar de solicitar 10 filas para una página, solicita 11 filas, pero muestra solo 10 y usa los valores en la fila 11 como la clave de inicio para la página siguiente".

Si espera que varios documentos emitan claves idénticas, necesitará usar startdocid además de la startkey de startkey para paginar correctamente. La razón es que la startkey sí sola ya no será suficiente para identificar de manera única una fila. Esos parámetros son inútiles si no proporciona una startkey . De hecho, CouchDB primero mirará el parámetro de la startkey , luego usará el parámetro startdocid para redefinir aún más el comienzo del rango si múltiples filas de startdocid potenciales tienen la misma clave pero diferentes identificadores de documentos. Lo mismo para el enddocid .