MongoDB
 sql >> Base de Dados >  >> NoSQL >> MongoDB

Paginação rápida com MongoDB


A paginação de seus dados é uma das operações mais comuns com o MongoDB. Um cenário típico é a necessidade de exibir seus resultados em partes em sua interface do usuário. Se você estiver processando seus dados em lote, também é importante acertar sua estratégia de paginação para que seu processamento de dados possa ser dimensionado.

Vamos ver um exemplo para ver as diferentes maneiras de percorrer dados no MongoDB. Neste exemplo, temos um banco de dados CRM de dados do usuário que precisamos percorrer e exibir 10 usuários por vez. Então, na verdade, nosso tamanho de página é 10. Aqui está a estrutura do nosso documento de usuário:
{
    _id,
    name,
    company,
    state
}


Abordagem 1:usando skip() e limit()


O MongoDB suporta nativamente a operação de paginação usando os comandos skip() e limit(). A diretiva skip(n) diz ao MongoDB que ele deve pular 'n' resultados, e a diretiva limit(n) instrui o MongoDB a limitar o comprimento do resultado a 'n' resultados. Normalmente, você usará as diretivas skip() e limit() com o cursor  - mas para ilustrar o cenário, fornecemos comandos de console que alcançariam os mesmos resultados. Além disso, por brevidade do código, o código de verificação de limites também é excluído:
//Page 1
db.users.find().limit (10)
//Page 2
db.users.find().skip(10).limit(10)
//Page 3
db.users.find().skip(20).limit(10)
........

Você entendeu a ideia. Em geral, para recuperar a página ‘n’ o código se parece com isso:
db.users.find().skip(pagesize*(n-1)).limit(pagesize)

No entanto, à medida que o tamanho dos seus dados aumenta, essa abordagem apresenta sérios problemas de desempenho. A razão é que toda vez que a consulta é executada, o conjunto de resultados completo é construído e, em seguida, o servidor precisa caminhar desde o início da coleta até o deslocamento especificado. À medida que seu deslocamento aumenta, esse processo fica cada vez mais lento. Além disso, esse processo não faz uso eficiente dos índices. Portanto, normalmente a abordagem 'skip()' e 'limit()' é útil quando você tem pequenos conjuntos de dados e, se estiver trabalhando com grandes conjuntos de dados, convém considerar outras abordagens.

Abordagem 2:usando find() e limit()


A razão pela qual a abordagem anterior não escala muito bem é o comando skip(), e o objetivo nesta seção é implementar a paginação sem usar o comando ‘skip()’. Para isso, vamos aproveitar a ordem natural dos dados armazenados, como um carimbo de data/hora ou um id armazenado no documento. Neste exemplo, vamos usar o ‘_id’ armazenado em cada documento. ‘_id’ é uma estrutura ObjectID do MongoDB que é uma estrutura de 12 bytes contendo um timestamp, usinado, processid, contador, etc. A ideia geral é a seguinte:

1. Recupere o _id do último documento na página atual
2. Recupere documentos maiores que este “_id” na próxima página
//Page 1
db.users.find().limit(pageSize);
//Find the id of the last document in this page
last_id = ...

//Page 2
users = db.users.find({'_id'> last_id}). limit(10);
//Update the last id with the id of the last document in this page
last_id = ...


Essa abordagem aproveita a ordem inerente que existe no campo “_id”. Além disso, como o campo “_id” é indexado por padrão, o desempenho da operação de localização é muito bom. Se o campo que você está usando não estiver indexado, seu desempenho será prejudicado – por isso é importante certificar-se de que o campo esteja indexado.

Além disso, se você quiser que seus dados sejam classificados em uma ordem específica para sua paginação, também poderá usar a cláusula sort() com a técnica acima. É importante garantir que o processo de classificação esteja aproveitando um índice para obter o melhor desempenho. Você pode usar o sufixo .explain() em sua consulta para determinar isso:
users = db.users.find({'_id'> last_id}). sort(..).limit(10);
//Update the last id with the id of the last document in this page
last_id = ...


Como sempre, se você tiver dúvidas ou comentários, sinta-se à vontade para entrar em contato conosco em [email protected].