Pergunta

Como eu iria sobre a implementação das consultas necessárias para a paginação?

Basicamente, quando página 1 é solicitada, obtenha as primeiras 5 entradas. Por página 2, obter o próximo 5 e assim por diante.

Eu pretendo usar isso através do módulo couchdb-python, mas que não deve fazer qualquer diferença para a implementação.

Foi útil?

Solução

O Guia CouchDB tem uma boa discussão de paginação, incluindo os lotes de código de exemplo, aqui: http://guide.couchdb.org/draft/recipes.html#pagination Aqui está seu algoritmo:

  • linhas Pedido rows_per_page + 1 da vista
  • linhas de exibição rows_per_page, armazenar última linha como next_startkey
  • Como a informação da página, mantenha startkey e next_startkey
  • Use os valores next_* para criar o próximo link, e usar os outros para criar o link anterior

NB .: A maneira correta para buscar páginas na CouchDB é especificando uma chave de partida, não um índice começando como você poderia pensar. Mas como você sabe o que tecla para iniciar a 2ª página em? A solução inteligente: "Em vez de solicitar 10 linhas para uma página, você solicitar 11 linhas, mas exibir apenas 10 e usar os valores na linha 11 como o StartKey para a próxima página"

Se você espera ter vários documentos emitem chaves idênticas, você vai precisar usar startdocid além startkey para paginar corretamente. A razão é que startkey por si só, não ser suficiente para identificar unicamente uma linha. Esses parâmetros são inúteis se você não fornecer um startkey. Na verdade, CouchDB vai olhar primeiro para o parâmetro startkey, então ele vai usar o parâmetro startdocid para mais redefinir o início do intervalo se várias linhas possíveis de olhar fixamente ter a mesma chave, mas diferentes IDs de documentos. Mesma coisa para o enddocid.

Outras dicas

O CouchDB HTTP Ver API dá muita margem para fazer paginação de forma eficiente.

O método mais simples seria usar startkey e count. Count é o número máximo de entradas CouchDB irá retornar para essa solicitação vista, algo que é até o seu design, e StartKey é onde você quer CouchDB para começar. Quando você solicita o ponto de vista que também irá dizer-lhe quantas entradas existem, o que lhe permite calcular quantas páginas haverá se você quiser mostrar que para os usuários.

Assim, o primeiro pedido não especificar um StartKey, apenas a contagem para o número de entradas que deseja mostrar. Você pode em seguida, anote a chave da última entrada retornou e usar isso como a chave de ignição para a próxima página. Nesta forma simples, você vai ter uma sobreposição, onde a última entrada de uma página é o primeiro do próximo. Se isso não é desejável é trivial simplesmente não exibir a última entrada da página.

Um método mais simples de fazer isso é usar o parâmetro de salto para trabalhar fora do documento inicial para a página, no entanto, este método deve ser usado com cautela. O parâmetro de ignorar simplesmente faz com que o motor interno para não retornar entradas que ele está interagindo sobre. Enquanto isso dá o comportamento desejado é muito mais lento do que encontrar o primeiro documento para a página por chave. Os mais documentos que são ignorados, o mais lento o pedido será.

Este é o que eu vim com até agora - para obter os IDs de todos os lugares, em seguida, recuperar os itens reais para o primeiro número x de IDs ..

Não é terrivelmente eficiente, mas mais do que recuperar todas as mensagens, em seguida, jogando a maior parte da distância. Dito isto, para minha surpresa, ele parecia correr muito rapidamente -. Corri o método posthelper.page() 100 vezes e levou cerca de 0,5 segundos

Eu não queria postar isso na questão real, por isso não influenciaria as respostas como muito - aqui está o 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
  • Aqui abaixo é a maneira recursiva eu ??encontrei:

    Tome duas variáveis ??

  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();

                           });
  });

  }
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top