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

Implementace stránkování v mongodb

Koncept, o kterém mluvíte, lze nazvat „forward paging“. Dobrým důvodem pro to je rozdíl od použití .skip() a .limit() modifikátory toto nelze použít k "návratu" na předchozí stránku nebo skutečně k "přeskočení" na konkrétní stránku. Přinejmenším ne s velkým úsilím ukládat „viděné“ nebo „objevené“ stránky, takže pokud chcete tento typ stránkování „odkazů na stránku“, pak je nejlepší zůstat u .skip() a .limit() přístup, navzdory výkonnostním nevýhodám.

Pokud je pro vás životaschopnou možností pouze „postoupit vpřed“, pak zde je základní koncept:

db.junk.find().limit(3)

{ "_id" : ObjectId("54c03f0c2f63310180151877"), "a" : 1, "b" : 1 }
{ "_id" : ObjectId("54c03f0c2f63310180151878"), "a" : 4, "b" : 4 }
{ "_id" : ObjectId("54c03f0c2f63310180151879"), "a" : 10, "b" : 10 }

Samozřejmě je to vaše první stránka s limitem 3 položek. Zvažte, že nyní s kódem iterujícím kurzor:

var lastSeen = null;
var cursor = db.junk.find().limit(3);

while (cursor.hasNext()) {
   var doc = cursor.next();
   printjson(doc);
   if (!cursor.hasNext())
     lastSeen = doc._id;
}

Takže iteruje kurzor a něco udělá, a když je pravda, že je dosažena poslední položka v kurzoru, uložíte lastSeen hodnotu na současné _id :

ObjectId("54c03f0c2f63310180151879")

Ve svých dalších iteracích pouze zadáte toto _id hodnota, kterou uchováte (v relaci nebo cokoli jiného) v dotazu:

var cursor = db.junk.find({ "_id": { "$gt": lastSeen } }).limit(3);

while (cursor.hasNext()) {
   var doc = cursor.next();
   printjson(doc);
   if (!cursor.hasNext())
     lastSeen = doc._id;
}

{ "_id" : ObjectId("54c03f0c2f6331018015187a"), "a" : 1, "b" : 1 }
{ "_id" : ObjectId("54c03f0c2f6331018015187b"), "a" : 6, "b" : 6 }
{ "_id" : ObjectId("54c03f0c2f6331018015187c"), "a" : 7, "b" : 7 }

A proces se opakuje znovu a znovu, dokud nelze získat žádné další výsledky.

To je základní proces pro přirozený řád, jako je _id . U něčeho jiného je to trochu složitější. Zvažte následující:

{ "_id": 4, "rank": 3 }
{ "_id": 8, "rank": 3 }
{ "_id": 1, "rank": 3 }    
{ "_id": 3, "rank": 2 }

Chcete-li to rozdělit na dvě stránky seřazené podle hodnocení, musíte v podstatě vědět, co jste „již viděli“, a vyloučit tyto výsledky. Takže při pohledu na první stránku:

var lastSeen = null;
var seenIds = [];
var cursor = db.junk.find().sort({ "rank": -1 }).limit(2);

while (cursor.hasNext()) {
   var doc = cursor.next();
   printjson(doc);
   if ( lastSeen != null && doc.rank != lastSeen )
       seenIds = [];
   seenIds.push(doc._id);
   if (!cursor.hasNext() || lastSeen == null)
     lastSeen = doc.rank;
}

{ "_id": 4, "rank": 3 }
{ "_id": 8, "rank": 3 }

V další iteraci chcete být menší nebo roven skóre „hodnocení“ lastSeen, ale také s vyloučením již viděných dokumentů. To provedete pomocí $nin operátor:

var cursor = db.junk.find(
    { "_id": { "$nin": seenIds }, "rank": "$lte": lastSeen }
).sort({ "rank": -1 }).limit(2);

while (cursor.hasNext()) {
   var doc = cursor.next();
   printjson(doc);
   if ( lastSeen != null && doc.rank != lastSeen )
       seenIds = [];
   seenIds.push(doc._id);
   if (!cursor.hasNext() || lastSeen == null)
     lastSeen = doc.rank;
}

{ "_id": 1, "rank": 3 }    
{ "_id": 3, "rank": 2 }

Kolik „seenId“ skutečně držíte, závisí na tom, jak „granulární“ jsou vaše výsledky, kde se tato hodnota pravděpodobně změní. V tomto případě můžete zkontrolovat, zda se aktuální skóre "rank" nerovná lastSeen hodnotu a zahoďte současné seenIds obsahu, takže příliš nenarůstá.

To jsou základní pojmy „dopředného stránkování“, které si můžete procvičit a naučit se.



  1. Výkon MongoDB Find:jeden složený index VS dva indexy s jedním polem

  2. Co je Procfile? a Web a pracovník

  3. Jaké jsou výhody použití databáze bez schémat, jako je MongoDB, ve srovnání s relační databází?

  4. Vytvořte aplikaci pro psaní poznámek pro Android pomocí MongoDB Stitch