Question

Comment procéder pour mettre en œuvre les requêtes nécessaires à la pagination?

En gros, lorsque la page 1 est demandée, obtenez les 5 premières entrées. Pour la page 2, obtenez les 5 suivants, etc.

.

Je prévois de l'utiliser via le module couchdb-python, mais cela ne devrait pas faire de différence pour la mise en œuvre.

Était-ce utile?

La solution

Le Le guide CouchDB contient une bonne discussion sur la pagination, y compris de nombreux exemples de code, ici: http://guide.couchdb.org/draft/recipes.html#pagination Voici leur algorithme:

  • Demander rows_per_page + 1 lignes à partir de la vue
  • Affichez rows_per_page , stockez la dernière ligne sous la forme next_startkey
  • Comme informations de page, conservez startkey et next_startkey
  • Utilisez les valeurs next _ * pour créer le lien suivant et utilisez les autres pour créer le lien précédent

N.B .: Le moyen approprié pour récupérer des pages dans CouchDB consiste à spécifier une clé de départ, pas un index de départ comme vous pourriez le penser. Mais comment savoir sur quelle touche démarrer la 2ème page? La solution intelligente: "Au lieu de demander 10 lignes pour une page, vous en demandez 11, mais vous n'en affichez que 10 et vous utilisez les valeurs de la 11ème ligne comme clé de départ pour la page suivante."

Si vous souhaitez que plusieurs documents émettent des clés identiques, vous devez utiliser startdocid en plus de startkey pour effectuer une pagination correcte. La raison en est que startkey ne suffira plus, à lui seul, à identifier une ligne. Ces paramètres sont inutiles si vous ne fournissez pas de startkey . En fait, CouchDB examinera d’abord le paramètre startkey , puis utilisera le paramètre startdocid pour redéfinir davantage le début de la plage si plusieurs lignes de référence potentielles ont la même clé. mais des identifiants de document différents. Même chose pour enddocid .

Autres conseils

La API de vue HTTP de CouchDB offre une marge de manœuvre suffisante pour effectuer une pagination efficace.

La méthode la plus simple utiliserait startkey et count . Count est le nombre maximal d'entrées que CouchDB renverra pour cette demande d'affichage, ce qui dépend de votre conception, et startkey est l'endroit où vous souhaitez que CouchDB démarre. Lorsque vous demandez l'affichage, il vous indique également le nombre d'entrées, ce qui vous permet de calculer le nombre de pages si vous souhaitez montrer cela aux utilisateurs.

Ainsi, la première demande ne spécifierait pas de clé de début, mais uniquement le nombre d'entrées à afficher. Vous pouvez ensuite noter la clé de la dernière entrée renvoyée et l'utiliser comme clé de départ pour la page suivante. Dans ce formulaire simple, vous obtiendrez un chevauchement, où la dernière entrée d'une page est la première de la suivante. Si cela n’est pas souhaitable, il est facile de ne pas afficher la dernière entrée de la page.

Une méthode plus simple consiste à utiliser le paramètre skip pour élaborer le document de départ de la page. Cette méthode doit toutefois être utilisée avec prudence. Le paramètre skip empêche simplement le moteur interne de renvoyer les entrées sur lesquelles il effectue une itération. Bien que cela donne le comportement souhaité, il est beaucoup plus lent que de trouver le premier document pour la page par clé. Plus le nombre de documents ignorés est important, plus la requête sera lente.

C’est ce que j’ai proposé jusqu’à présent: obtenir les identifiants de toutes les publications, puis récupérer les éléments réels pour le premier nombre x d'identifiants.

Ce n’est pas très efficace, mais plus que de récupérer tous les messages, puis de les jeter. Cela dit, à ma grande surprise, le processus a semblé très rapide: j'ai exécuté la méthode posthelper.page () 100 fois, ce qui a pris environ 0,5 seconde.

Je ne voulais pas poster ceci dans la question, donc cela n'influencerait pas autant les réponses - voici le code:

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
  • Voici ci-dessous la manière récursive que j'ai trouvée:

    Prenez deux variables

  var lastOffset = 0; var counter = 0;

  function someRecursive(lastOffset,counter) {

  queryView(db, whereClause).then(result => {
      var rows_per_page = 5; 

//formula below 
var page = Math.floor((lastOffset == 0 ? 0: (result.offset - lastOffset) +

  (rows_per_page * counter)) /  rows_per_page) + 1;

   var skip = page * rows_per_page;
  if (somerecursionexitcondition) {
                   counter = lastOffset == 0 ? lastOffset: counter + 1;
                   lastOffset =result.offset;
              someRecursive(lastOffset, counter).then(result => {
                               resolve();

                           });
  });

  }
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top