Es wird gesagt, dass die Verwendung von skip () für die Paginierung in der MongoDB-Sammlung mit vielen Datensätzen langsam ist und nicht empfohlen wird.
Fernkampf-Paginierung (basierend auf> _id-Vergleich) könnte verwendet werden
db.items.find({_id: {$gt: ObjectId('4f4a3ba2751e88780b000000')}});
Es ist gut für die Anzeige von prev. & next-Schaltflächen - aber es ist nicht sehr einfach zu implementieren, wenn Sie die tatsächlichen Seitenzahlen 1 ... 5 6 7 ... 124 anzeigen möchten - Sie müssen vorberechnen, ab welcher "_id" jede Seite beginnt.
Ich habe also zwei Fragen:
1) Wann sollte ich mir darüber Sorgen machen? Wenn es "zu viele Datensätze" mit einer merklichen Verlangsamung für skip () gibt? 1 000? 1 000 000?
2) Was ist der beste Ansatz, um Links mit tatsächlichen Seitenzahlen anzuzeigen, wenn eine Fernkampf-Paginierung verwendet wird?
quelle
Es ist schwierig, eine allgemeine Antwort zu geben, da dies stark davon abhängt, welche Abfrage (oder Abfragen) Sie verwenden, um die angezeigten Ergebnisse zu erstellen. Wenn die Ergebnisse nur anhand des Index gefunden werden können und in der Indexreihenfolge angezeigt werden, kann db.dataset.find (). Limit (). Skip () auch bei einer großen Anzahl von Sprüngen eine gute Leistung erbringen. Dies ist wahrscheinlich der einfachste Ansatz zum Codieren. Aber selbst in diesem Fall können Sie die Seitenzahlen zwischenspeichern und an Indexwerte binden, um sie beispielsweise für die zweite und dritte Person, die beispielsweise Seite 71 anzeigen möchte, zu beschleunigen.
In einem sehr dynamischen Datensatz, in dem Dokumente hinzugefügt und entfernt werden, während eine andere Person Daten durchsucht, ist ein solches Caching schnell veraltet, und die Limit- und Skip-Methode ist möglicherweise die einzige, die zuverlässig genug ist, um gute Ergebnisse zu erzielen.
quelle
Ich habe kürzlich das gleiche Problem festgestellt, als ich versuchte, eine Anfrage zu paginieren, während ich ein Feld verwendete, das nicht eindeutig war, zum Beispiel "Vorname". Die Idee dieser Abfrage ist es, die Paginierung in einem nicht eindeutigen Feld ohne Verwendung von skip () implementieren zu können.
Das Hauptproblem hierbei ist die Möglichkeit, ein Feld abzufragen, das nicht eindeutig "Vorname" ist, da Folgendes passieren wird:
Daher bestand die Lösung darin, den $ match-Teil der Abfrage eindeutig zu machen, indem das Zielsuchfeld mit einem sekundären Feld kombiniert wurde, um eine eindeutige Suche zu erstellen.
Aufsteigende Reihenfolge:
db.customers.aggregate([ {$match: { $or: [ {$and: [{'FirstName': 'Carlos'}, {'_id': {$gt: ObjectId("some-object-id")}}]}, {'FirstName': {$gt: 'Carlos'}}]}}, {$sort: {'FirstName': 1, '_id': 1}}, {$limit: 10} ])
Absteigende Reihenfolge:
db.customers.aggregate([ {$match: { $or: [ {$and: [{'FirstName': 'Carlos'}, {'_id': {$gt: ObjectId("some-object-id")}}]}, {'FirstName': {$lt: 'Carlos'}}]}}, {$sort: {'FirstName': -1, '_id': 1}}, {$limit: 10} ])
Der $ match-Teil dieser Abfrage verhält sich im Grunde genommen wie eine if-Anweisung: Wenn firstName "Carlos" ist, muss er auch größer als diese ID sein. Wenn firstName nicht gleich "Carlos" ist, muss er größer als "Carlos" sein.
Das einzige Problem ist, dass Sie nicht zu einer bestimmten Seitenzahl navigieren können (dies kann wahrscheinlich mit einer gewissen Code-Manipulation durchgeführt werden), aber abgesehen davon hat es mein Problem mit der Paginierung für nicht eindeutige Felder gelöst, ohne überspringen zu müssen, was viel Speicher und Verarbeitung verbraucht Leistung, wenn Sie am Ende des Datensatzes angelangt sind, nach dem Sie fragen.
quelle