MongoDB
 sql >> база данни >  >> NoSQL >> MongoDB

Внедряване на пагинация в mongodb

Концепцията, за която говорите, може да се нарече "пренасочване на страници". Добра причина за това е за разлика от използването на .skip() и .limit() модификатори това не може да се използва за "връщане" към предишна страница или наистина "прескачане" на конкретна страница. Поне не с много усилия да съхранявате „виждани“ или „открити“ страници, така че ако този тип страница „връзки към страница“ е това, което искате, тогава е най-добре да се придържате към .skip() и .limit() подход, въпреки недостатъците на производителността.

Ако за вас е жизнеспособна опция само да "вървите напред", тогава ето основната концепция:

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 }

Разбира се, това е първата ви страница с ограничение от 3 елемента. Помислете за това сега с код, повтарящ курсора:

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

Така че итерира курсора и прави нещо, и когато е вярно, че последният елемент в курсора е достигнат, вие съхранявате lastSeen стойност към настоящия _id :

ObjectId("54c03f0c2f63310180151879")

В следващите си итерации просто подавате този _id стойност, която запазвате (в сесия или каквото и да е) към заявката:

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 }

И процесът се повтаря отново и отново, докато не могат да се получат повече резултати.

Това е основният процес за естествен ред като _id . За нещо друго става малко по-сложно. Помислете за следното:

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

За да разделите това на две страници, сортирани по ранг, тогава това, което по същество трябва да знаете, е това, което „вече сте виждали“ и да изключите тези резултати. Така че гледам на първа страница:

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 }

При следващата итерация искате да бъдете по-малки или равни на последния „ранг“ резултат, но също така да изключите тези вече видяни документи. Правите това с $nin оператор:

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 }

Колко „seenIds“ всъщност държите зависи от това колко „гранулирани“ са резултатите ви, където тази стойност вероятно ще се промени. В този случай можете да проверите дали текущият "ранг" резултат не е равен на lastSeen стойност и изхвърлете настоящите seenIds съдържание, така че да не нараства много.

Това са основните концепции за „пренасочване на страници“, които да практикувате и да научите.



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. реплика Задайте mongo docker-compose

  2. Има ли начин да отпечатате "красиво" изхода на обвивката на MongoDB във файл?

  3. Заявка за получаване на данни за последните X минути с Mongodb

  4. MongoDB $toLower

  5. mongodb $exists винаги връща 0