Berechnen Sie den Sprungwert für einen bestimmten Datensatz für sortiertes Paging

Lesezeit: 3 Minuten

Berechnen Sie den Sprungwert fur einen bestimmten Datensatz fur sortiertes
Garbit

Ich versuche, den Skip-Wert für einen bestimmten Datensatz in einer Mongo-DB-Sammlung mit dem PHP-Treiber zu berechnen. Finden Sie also anhand eines bestimmten Datensatzes den Index dieses Datensatzes innerhalb der gesamten Sammlung heraus. Ist das möglich?

Derzeit wähle ich alle Datensätze aus und mache manuell einen Index für das Array von Ergebnissen.

Berechnen Sie den Sprungwert fur einen bestimmten Datensatz fur sortiertes
Blakes Sieben

Dies wird als „Vorwärtsblättern“ bezeichnet. Dies ist ein Konzept, das Sie verwenden können, um „effizient“ durch Ergebnisse in einer „Vorwärts“-Richtung zu blättern, wenn Sie „sortierte“ Ergebnisse verwenden.

JavaScript-Logik enthalten (weil sie in der Shell funktioniert), aber nicht schwer zu übersetzen.

Das Konzept im Allgemeinen:

{ "_id": 1, "a": 3 },
{ "_id": 2, "a": 3 },
{ "_id": 3, "a": 3 },
{ "_id": 4, "a": 2 },
{ "_id": 5, "a": 1 },
{ "_id": 6, "a": 0 }

Betrachten Sie diese “bereits sortierten” Dokumente (der Einfachheit halber) als Beispiel für Ergebnisse, die wir nach “zwei” Elementen pro Seite “blättern” möchten.

Im ersten Fall gehst du so vor:

var lastVal = null,
    lastSeen = [];

db.collection.find().sort({ "a": -1 }).limit(2).forEach(function(doc) {
    if ( lastVal != doc.a ) {
        lastSeen = [];
    }
    lastVal = doc.a;
    lastSeen.push( doc._id );
    // do something useful with each document matched
});

Jetzt die lastVal und lastSeen sind etwas, das Sie in so etwas wie einer “Sitzungsvariablen” speichern, auf die bei der nächsten Anfrage in Bezug auf Webanwendungen zugegriffen werden kann, oder auf andere Weise etwas Ähnliches, wo dies nicht der Fall ist.

Was sie jedoch enthalten sollten, sind der allerletzte Wert, nach dem Sie sortiert haben, und die Liste der “einzigartigen”. _id Werte, die seit diesem Wert gesehen wurden, haben sich nicht geändert. Somit:

lastVal = 3,
lastSeen = [1,2];

Der Punkt ist, dass Sie diese Variablen für etwas wie das Folgende verwenden möchten, wenn die Anfrage für die “nächste Seite” kommt:

var lastVal = 3,
    lastSeen = [1,2];

db.collection.find({ 
    "_id": { "$nin": lastSeen }, 
    "a": { "$lte": lastVal }
}).sort({ "a": -1 }).limit(2).forEach(function(doc) {
    if ( lastVal != doc.a ) {
        lastSeen = [];
    }
    lastVal = doc.a;
    lastSeen.push( doc._id );
    // do something useful with each document matched
});

Das bewirkt, dass alle Werte von “ausgeschlossen” werden _id die eingetragen sind lastSeen aus der Ergebnisliste, sowie darauf achten, dass alle Ergebnisse „kleiner oder gleich“ (absteigende Reihenfolge) sein müssen lastVal für das Sortierfeld “a” aufgezeichnet.

Dies ergibt die nächsten beiden Ergebnisse in der Auflistung:

{ "_id": 3, "a": 3 },
{ "_id": 4, "a": 2 },

Aber nach der Verarbeitung sehen unsere Werte jetzt so aus:

lastVal = 2,
lastSeen = [4];

Jetzt folgt also die Logik, dass Sie den anderen nicht ausschließen müssen _id Werte vorher gesehen, da Sie nur wirklich nach Werten von “a” suchen, die “kleiner oder gleich” sind lastVal und da es nur “einen” gab _id Wert, der bei diesem Wert gesehen wird, schließt dann nur diesen aus.

Dies ergibt natürlich die nächste Seite zur Verwendung des gleichen Codes wie oben:

{ "_id": 5, "a": 1 },
{ "_id": 6, "a": 0 }

Dies ist im Allgemeinen der effizienteste Weg, um durch Ergebnisse “vorzublättern”, und ist besonders nützlich für das effiziente Blättern von “sortierten” Ergebnissen.

Wenn Sie jedoch zur Seite “springen” möchten 20 oder ähnliche Maßnahmen zu irgendeinem Zeitpunkt, dann ist dies nichts für Sie. Sie bleiben beim Traditionellen hängen .skip() und .limit() Ansatz, dies anhand der “Seitenzahl” tun zu können, da es keine andere vernünftige Möglichkeit gibt, dies zu “berechnen”.

Es hängt also alles davon ab, wie Ihre Anwendung “Paging” implementiert und womit Sie leben können. Der .skip() und .limit() -Ansatz leidet unter der Leistung des “Überspringens” und kann vermieden werden, indem der Ansatz hier verwendet wird.

Wenn Sie andererseits „zur Seite springen“ möchten, ist „Überspringen“ Ihre einzige wirkliche Option, es sei denn, Sie möchten einen „Cache“ mit Ergebnissen erstellen. Aber das ist ein ganz anderes Thema.

  • Fantastische Antwort, sehr zu schätzen 🙂

    – Garbit

    6. Juli 15 um 10:41 Uhr

.

734840cookie-checkBerechnen Sie den Sprungwert für einen bestimmten Datensatz für sortiertes Paging

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy