sql >> Databáze >  >> NoSQL >> MongoDB

Vypočítat hodnotu přeskočení pro daný záznam pro seřazené stránkování

Toto se nazývá „dopředné stránkování“, což je koncept, který můžete použít k „efektivnímu listování“ výsledky ve směru „dopředu“, když používáte „seřazené“ výsledky.

Logika JavaScriptu je zahrnuta (protože funguje v prostředí), ale není těžké ji přeložit.

Pojem obecně:

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

Zvažte tyto „již seřazené“ dokumenty (pro pohodlí) jako příklad výsledků, které chceme „stránkovat“ po „dvou“ položkách na stránku.

V prvním případě uděláte něco takového:

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
});

Nyní ty lastVal a lastSeen jsou něco, co ukládáte do něčeho jako "proměnná relace", ke které lze přistupovat při dalším požadavku z hlediska webových aplikací, nebo jinak něco podobného, ​​kde ne.

Měly by však obsahovat úplně poslední hodnotu, podle které jste třídili, a seznam „unikátních“ _id hodnoty, které byly pozorovány od té doby, co se tato hodnota nezměnila. Proto:

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

Jde o to, že když přijde požadavek na "další stránku", chcete tyto proměnné použít pro něco takového:

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
});

To znamená "vyloučit" všechny hodnoty _id které jsou zaznamenány v lastSeen ze seznamu výsledků a také se ujistěte, že všechny výsledky musí být „menší nebo rovno“ ( sestupné pořadí ) lastVal zaznamenané pro třídicí pole "a".

Výsledkem jsou další dva výsledky v kolekci:

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

Ale po zpracování naše hodnoty nyní vypadají takto:

lastVal = 2,
lastSeen = [4];

Nyní tedy z logiky vyplývá, že nemusíte vylučovat další _id hodnoty, které jste viděli dříve, protože ve skutečnosti hledáte pouze hodnoty "a", než jsou "menší nebo rovno" lastVal a protože existoval pouze "jeden" _id hodnota viděná při této hodnotě, pak vyloučí pouze tuto.

To samozřejmě vede k další stránce s použitím stejného kódu jako výše:

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

To je obecně nejefektivnější způsob, jak „přeposílat stránku“ přes výsledky, a je zvláště užitečný pro efektivní stránkování „seřazených“ výsledků.

Pokud však chcete "skočit" na stránku 20 nebo podobnou akci v jakékoli fázi, pak to není pro vás. Uvízli jste u tradičního .skip() a .limit() přístup, abyste to mohli udělat podle "čísla stránky", protože neexistuje žádný jiný racionální způsob, jak to "spočítat".

Vše tedy závisí na tom, jak vaše aplikace implementuje „stránkování“ a s čím dokážete žít. .skip() a .limit() přístup trpí výkonem „přeskakování“ a lze se mu vyhnout použitím tohoto přístupu.

Na druhou stranu, pokud chcete „skočit na stránku“, pak je „přeskočení“ vaší jedinou skutečnou možností, pokud nechcete vytvořit „mezipaměť“ výsledků. Ale to je úplně jiný problém.




  1. Java MongoDB Object Versioning

  2. MongoDB min

  3. DigitalOcean pod má neomezené okamžité nároky PersistentVolumeClaims

  4. Pole Mongodb $push a $pull