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

Изчислете стойността на пропускане за даден запис за сортирани страници

Това се нарича „пренасочване на страници“, което е концепция, която можете да използвате за „ефективно прелистване“ чрез резултати в посока „напред“, когато използвате „сортирани“ резултати.

Включена логика на JavaScript (защото работи в обвивката), но не е трудно за превод.

Концепцията като цяло:

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

Разгледайте тези „вече сортирани“ документи (за удобство) като пример за резултати, които искаме да „страница“ по „два“ елемента на страница.

В първия случай правите нещо подобно:

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

Сега тези lastVal и lastSeen са нещо, което съхранявате в нещо като „променлива на сесията“, което може да бъде достъпно при следващата заявка по отношение на уеб приложения или по друг начин нещо подобно, където не.

Това, което трябва да съдържат обаче, са последната стойност, по която сортирате, и списъкът с "уникални" _id стойности, които са били видени, тъй като тази стойност не се е променила. Следователно:

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

Въпросът е, че когато се появи заявката за "следваща страница", тогава искате да използвате тези променливи за нещо подобно:

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

Това, което прави, е "изключва" всички стойности на _id които са записани в lastSeen от списъка с резултати, както и се уверете, че всички резултати трябва да са "по-малки или равни на" ( низходящ ред ) lastVal записано за полето за сортиране "a".

Това дава следните два резултата в колекцията:

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

Но след обработката нашите стойности вече изглеждат така:

lastVal = 2,
lastSeen = [4];

Така че сега логиката следва, че не е необходимо да изключвате другия _id стойности, виждани преди, тъй като наистина търсите само стойности на "a", отколкото са "по-малки или равни на" lastVal и тъй като имаше само "един" _id стойност, видяна при тази стойност, след това изключвайте само тази.

Това, разбира се, води до следващата страница с използването на същия код като малко по-горе:

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

Това е най-ефективният начин за „пренасочване на страница“ чрез резултати като цяло и е особено полезен за ефективно пейджиране на „сортирани“ резултати.

Ако обаче искате да "прескочите" на страница 20 или подобно действие на всеки етап, то това не е за вас. Вие сте останали с традиционния .skip() и .limit() подход, за да можете да направите това чрез „номер на страница“, тъй като няма друг рационален начин да „изчислите“ това.

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

От друга страна, ако искате да „прескочите към страница“, тогава „пропускането“ е единствената ви реална опция, освен ако не искате да изградите „кеш“ с резултати. Но това е съвсем друг въпрос.




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Приложението не успя да стартира (порт 8080) не е налично

  2. MongoDB и CodeIgniter

  3. Определяне на най-добрата архитектура за внедряване на клъстер MongoDB

  4. Как да получите всички резултати, ако полето за отвиване не съществува в mongodb

  5. MongoDB $lt Оператор на конвейер за агрегиране