72 votes

MongoDB variait de pagination

Il est dit que l'utilisation de skip() pour la pagination dans la collection MongoDB avec le nombre d'enregistrements est lent et n'est pas recommandé.

Variait de pagination (sur la base >_id comparaison) pourrait être utilisé

db.items.find({_id: {$gt: ObjectId('4f4a3ba2751e88780b000000')}});

C'est bon pour l'affichage précédent. et à côté des boutons - mais ce n'est pas très facile à mettre en œuvre lorsque vous souhaitez afficher une réelle numéros de page 1 ... 5 6 7 ... 124 - vous besoin de pré-calculer à partir de laquelle "_id" chaque page commence.

J'ai donc deux questions:

1) Quand devrais-je commencer à s'inquiéter? Quand il y a "trop d'enregistrements" avec ralentissement notable pour sauter()? 1 000? 1 000 000?

2) Quelle est la meilleure approche pour afficher des liens avec des numéros de page réelle lors de l'utilisation variait de pagination?

100voto

Sergio Tulentsev Points 82783

Bonne question!

"Combien est trop?" - que, bien sûr, dépend de la taille des données et des exigences de performance. J'ai, personnellement, mal à l'aise quand je me passer de plus de 500 à 1000 enregistrements.

La réponse réelle dépend de vos besoins. Voici ce que modernes sites (ou, au moins, certains d'entre eux).

Tout d'abord, barre de navigation ressemble à ceci:

1 2 3 ... 457

Ils le final nombre de page total nombre d'enregistrement et taille de la page. Nous allons aller à la page 3. Auquel participeront à sauter du premier enregistrement. Quand les résultats arrivent, vous connaissez l'id du premier enregistrement à la page 3.

1 2 3 4 5 ... 457

Passons un peu plus et aller à la page 5.

1 ... 3 4 5 6 7 ... 457

Vous obtenez l'idée. À chaque point de vous voir en premier, dernier et actuel pages, et aussi deux pages en avant et en arrière à partir de la page en cours.

Les requêtes

var current_id; // id of first record on current page.

// go to page current+N
db.collection.find({_id: {$gt: current_id}}).
              skip(N * page_size).
              limit(page_size).
              sort({_id: 1});

// go to page current-N
db.collection.find({_id: {$lt: current_id}}).
              skip((N-1)*page_size).
              limit(page_size).
              sort({_id: 1});

6voto

Tad Marshall Points 915

Il est difficile de donner une réponse générale, car cela dépend beaucoup de ce que la requête (ou requêtes) que vous utilisez pour construire l'ensemble des résultats qui sont affichés. Si les résultats peuvent être trouvés en utilisant seulement l'index et sont présentés dans l'ordre d'index puis db.jeu de données.find().limite().skip() peut bien fonctionner, même avec un grand nombre de sauts. C'est probablement l'approche la plus facile à coder. Mais même dans ce cas, si vous pouvez mettre en cache les numéros de page et de les attacher à des valeurs de l'indice, vous pouvez le rendre plus rapide pour la deuxième et à la troisième personne qui veut l'affichage de la page 71, par exemple.

Dans un très dynamique dataset où les documents seront ajoutés et supprimés tandis que quelqu'un d'autre est de pagination à travers les données, telles la mise en cache du devenir obsolètes rapidement et de la limite et de la méthode skip peut-être le seul assez fiables pour donner de bons résultats.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X