Das Durchsuchen Ihrer Daten ist eine der häufigsten Operationen mit MongoDB. Ein typisches Szenario ist die Notwendigkeit, Ihre Ergebnisse in Blöcken in Ihrer Benutzeroberfläche anzuzeigen. Wenn Sie Ihre Daten stapelweise verarbeiten, ist es auch wichtig, Ihre Paging-Strategie richtig zu wählen, damit Ihre Datenverarbeitung skaliert werden kann.
Lassen Sie uns ein Beispiel durchgehen, um die verschiedenen Möglichkeiten zum Blättern durch Daten in MongoDB zu sehen. In diesem Beispiel haben wir eine CRM-Datenbank mit Benutzerdaten, die wir durchblättern und 10 Benutzer gleichzeitig anzeigen müssen. Unsere Seitengröße ist also tatsächlich 10. Hier ist die Struktur unseres Benutzerdokuments:
{ _id, name, company, state }
Ansatz 1:Verwendung von skip() und limit()
MongoDB unterstützt nativ den Paging-Vorgang mit den Befehlen skip() und limit(). Die Direktive skip(n) teilt MongoDB mit, dass sie „n“ Ergebnisse überspringen soll, und die Direktive limit(n) weist MongoDB an, dass sie die Ergebnislänge auf „n“ Ergebnisse begrenzen soll. Normalerweise verwenden Sie die Anweisungen skip() und limit() mit Ihrem Cursor – aber um das Szenario zu veranschaulichen, stellen wir Konsolenbefehle bereit, die dieselben Ergebnisse erzielen würden. Der Kürze des Codes halber ist auch der Grenzwertüberprüfungscode ausgeschlossen:
//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) ........
Du hast die Idee. Im Allgemeinen sieht der Code zum Abrufen von Seite 'n' so aus:
db.users.find().skip(pagesize*(n-1)).limit(pagesize)
Mit zunehmender Größe Ihrer Daten führt dieser Ansatz jedoch zu ernsthaften Leistungsproblemen. Der Grund dafür ist, dass jedes Mal, wenn die Abfrage ausgeführt wird, die vollständige Ergebnismenge aufgebaut wird und der Server dann vom Beginn der Sammlung bis zum angegebenen Offset gehen muss. Mit zunehmendem Offset wird dieser Vorgang immer langsamer. Außerdem nutzt dieser Prozess die Indizes nicht effizient. Daher ist der Ansatz „skip()“ und „limit()“ normalerweise nützlich, wenn Sie kleine Datensätze haben, und wenn Sie mit großen Datensätzen arbeiten, sollten Sie andere Ansätze in Betracht ziehen.
Ansatz 2:Verwendung von find() und limit()
Der Grund dafür, dass der vorherige Ansatz nicht sehr gut skaliert, ist der Befehl skip(), und das Ziel in diesem Abschnitt ist es, Paging ohne Verwendung des Befehls „skip()“ zu implementieren. Dazu nutzen wir die natürliche Reihenfolge in den gespeicherten Daten wie einen Zeitstempel oder eine im Dokument gespeicherte ID. In diesem Beispiel verwenden wir die in jedem Dokument gespeicherte „_id“. „_id“ ist eine MongoDB-ObjectID-Struktur, die eine 12-Byte-Struktur ist, die einen Zeitstempel, eine bearbeitete, eine Prozess-ID, einen Zähler usw. enthält. Die Grundidee ist wie folgt:
1. Rufen Sie die _id des letzten Dokuments auf der aktuellen Seite ab
2. Rufen Sie auf der nächsten Seite Dokumente ab, die größer als diese „_id“ sind
//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 = ...
Dieser Ansatz nutzt die inhärente Reihenfolge, die im Feld „_id“ vorhanden ist. Da das Feld „_id“ standardmäßig indiziert ist, ist die Leistung des Suchvorgangs sehr gut. Wenn das von Ihnen verwendete Feld nicht indexiert ist, leidet Ihre Leistung – daher ist es wichtig sicherzustellen, dass dieses Feld indexiert ist.
Wenn Sie möchten, dass Ihre Daten für Ihr Paging in einer bestimmten Reihenfolge sortiert werden, können Sie außerdem die sort()-Klausel mit der obigen Technik verwenden. Es ist wichtig sicherzustellen, dass der Sortierprozess einen Index nutzt, um die beste Leistung zu erzielen. Sie können das Suffix .explain() für Ihre Abfrage verwenden, um dies festzustellen:
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 = ...
Wenn Sie Fragen oder Kommentare haben, können Sie sich wie immer gerne unter [email protected] an uns wenden.