Jak paginować za pomocą Mongoose w Node.js?

231

Piszę aplikację internetową za pomocą Node.js i mangusty. Jak mogę podzielić strony na wyniki otrzymane z .find()połączenia? Chciałbym funkcjonalność porównywalną z "LIMIT 50,100"SQL.

Tomasz
źródło
Użyj pomijania i ograniczania właściwości podczas wyszukiwania danych z kolekcji.
Arun Sahani,
Ten link może być użyty dla ciebie szczegółowo. laxmanchavda.blogspot.com/2018/06/...
Laxman

Odpowiedzi:

278

Jestem bardzo rozczarowany zaakceptowanymi odpowiedziami na to pytanie. To nie będzie skalowane. Jeśli czytasz drobny druk na kursor.skip ():

Metoda kursor.skip () jest często droga, ponieważ wymaga od serwera przejścia od początku kolekcji lub indeksu w celu uzyskania przesunięcia lub pominięcia pozycji przed rozpoczęciem zwracania wyniku. Gdy przesunięcie (np. PageNumber powyżej) wzrasta, kursor.skip () będzie wolniejszy i bardziej obciążający procesor. Przy większych kolekcjach kursor.skip () może zostać powiązany z operacją we / wy.

Aby uzyskać podział na strony w skalowalny sposób, należy połączyć limit () z co najmniej jednym kryterium filtru, data „Utworzony” odpowiada wielu celom.

MyModel.find( { createdOn: { $lte: request.createdOnBefore } } )
.limit( 10 )
.sort( '-createdOn' )
Chris Hinkle
źródło
105
Ale jak uzyskać drugą stronę z tego zapytania bez pomijania? Jeśli oglądasz 10 wyników na stronie, a jest 100 wyników, jak zdefiniować wartość przesunięcia lub pominięcia? Nie odpowiadasz na pytanie o paginację, więc nie możesz być „rozczarowany”, chociaż jest to ważna uwaga. Chociaż ten sam problem dotyczy przesunięcia MySQL, ogranicz. Musi przejść drzewo do odsunięcia przed zwróceniem wyników. Wziąłbym to z odrobiną soli, jeśli twoje zestawy wyników są mniejsze niż 1 mililitr i nie ma żadnego możliwego do zachowania uderzenia wydajności, użyj skip ().
Lex
13
Jestem noob, jeśli chodzi o mongoose / mongodb, ale aby odpowiedzieć na pytanie Lexa, wydaje się, że ponieważ wyniki są uporządkowane według ' -createdOn', zamienisz wartość request.createdOnBeforena najmniejszą wartość createdOnzwróconą w poprzednim zestawie wyników, i następnie
Terry Lewis,
9
@JoeFrambach Żądanie w oparciu o utworzony wydaje się problematyczne. Skip został osadzony bez powodu. Dokumenty ostrzegają tylko przed spadkiem wydajności cyklicznym przez indeks btree, co ma miejsce w przypadku wszystkich DBMS. Dla użytkowników pytanie „coś porównywalnego MySQL do LIMIT 50 100” .skip jest dokładnie w porządku.
Lex.
8
Chociaż jest interesujący, problem z tą odpowiedzią, jak zauważa komentarz @Lex, polega na tym, że można tylko pomijać „przewijanie” lub „przewijanie” wyników - nie można mieć „stron”, na które można było przejść (np. Strona 1, Strona 2 , Strona 3) bez wielokrotnego zapytania sekwencyjnego w celu ustalenia, od czego zacząć paginację, co, jak podejrzewam, w większości przypadków będzie wolniejsze niż tylko pomijanie. Oczywiście może nie być konieczne dodanie możliwości przechodzenia do określonych stron.
Iain Collins,
20
Ta odpowiedź zawiera interesujące punkty, ale nie odpowiada na pierwotnie zadane pytanie.
steampowered
227

Po bliższym przyjrzeniu się Mongoose API z informacjami dostarczonymi przez Rodolphe, wymyśliłem to rozwiązanie:

MyModel.find(query, fields, { skip: 10, limit: 5 }, function(err, results) { ... });
Tomasz
źródło
21
Co powiesz na „liczyć”? Musisz to wiedzieć, ile jest stron.
Aleksey Saatchi
36
Nie skaluje się.
Chris Hinkle
4
Wyjaśnienie Chrisa Hinkle'a, dlaczego to się nie skaluje: stackoverflow.com/a/23640287/165330 .
imme
7
@ChrisHinkle Wydaje się, że tak jest w przypadku wszystkich DBMS. Komentarz Lexa poniżej powiązanej odpowiedzi wydaje się wyjaśniać więcej.
csotiriou
2
@Avij yeah. Użyłem do tego identyfikatora. to, co tam robisz, to wysyłanie ostatniego identyfikatora rekordów z powrotem na serwer i pobieranie rekordów o identyfikatorze większym niż wysłany. Po zindeksowaniu Id będzie znacznie szybciej
George Bailey,
108

Paginacja za pomocą mangusty, ekspresu i jadeitu - oto link do mojego bloga z bardziej szczegółowymi informacjami

var perPage = 10
  , page = Math.max(0, req.param('page'))

Event.find()
    .select('name')
    .limit(perPage)
    .skip(perPage * page)
    .sort({
        name: 'asc'
    })
    .exec(function(err, events) {
        Event.count().exec(function(err, count) {
            res.render('events', {
                events: events,
                page: page,
                pages: count / perPage
            })
        })
    })
Madhusudhan
źródło
26
Dziękujemy za opublikowanie odpowiedzi! Przeczytaj uważnie FAQ dotyczące autopromocji . Należy również pamiętać, że jest to konieczne , aby umieścić disclaimer każdym razem, gdy odwołują się do swojej własnej strony / produktu.
Andrew Barber,
Math.max(0, undefined)wróci undefined, To zadziałało dla mnie:let limit = Math.abs(req.query.limit) || 10; let page = (Math.abs(req.query.page) || 1) - 1; Schema.find().limit(limit).skip(limit * page)
Monfa.red
55

Możesz łańcuch po prostu tak:

var query = Model.find().sort('mykey', 1).skip(2).limit(5)

Wykonaj zapytanie za pomocą exec

query.exec(callback);
Rodolphe
źródło
Dziękujemy za odpowiedź, w jaki sposób dodawane jest połączenie zwrotne z wynikiem?
Thomas
2
execFind (funkcja (... na przykład: var page = req.param('p'); var per_page = 10; if (page == null) { page = 0; } Location.count({}, function(err, count) { Location.find({}).skip(page*per_page).limit(per_page).execFind(function(err, locations) { res.render('index', { locations: locations }); }); });
todd
9
uwaga: to nie będzie działać w trybie mangusty , ale będzie działać w trybie mongodb-native-driver.
Jesse
39

W takim przypadku możesz dodać zapytanie pagei / lub limitadres URL jako ciąg zapytania.

Na przykład:
?page=0&limit=25 // this would be added onto your URL: http:localhost:5000?page=0&limit=25

Ponieważ byłoby to Stringkonieczne, musimy go przekonwertować na wartość Numberdla naszych obliczeń. Zróbmy to za pomocą parseIntmetody i podajmy też wartości domyślne.

const pageOptions = {
    page: parseInt(req.query.page, 10) || 0,
    limit: parseInt(req.query.limit, 10) || 10
}

sexyModel.find()
    .skip(pageOptions.page * pageOptions.limit)
    .limit(pageOptions.limit)
    .exec(function (err, doc) {
        if(err) { res.status(500).json(err); return; };
        res.status(200).json(doc);
    });

BTW Podział na strony zaczyna się od0

CENT1PEDE
źródło
5
proszę dodać `{page: parseInt (req.query.page) || 0, ...} do parametru.
imalik8088
@ imalik8088 Dziękujemy, jednak parametry ciągu AFAIK są obsługiwane automatycznie mongoose.
CENT1PEDE
1
Spodziewałem się takiego zachowania, ale w moim przypadku nie mogło to być ukryte i pokazywanie mi błędu
imalik8088,
@ imalik8088 To dziwne. Może jeśli mógłbyś pokazać błąd reprodukcji, mogę edytować moją odpowiedź. Dzięki.
CENT1PEDE
2
Czy to spowodowałoby, że mangusta znalazłaby każdy rekord przed zastosowaniem warunków?
FluffyBeing
37

Możesz użyć małego pakietu o nazwie Mongoose Paginate, który ułatwia.

$ npm install mongoose-paginate

Następnie w swoich trasach lub kontrolerze po prostu dodaj:

/**
 * querying for `all` {} items in `MyModel`
 * paginating by second page, 10 items per page (10 results, page 2)
 **/

MyModel.paginate({}, 2, 10, function(error, pageCount, paginatedResults) {
  if (error) {
    console.error(error);
  } else {
    console.log('Pages:', pageCount);
    console.log(paginatedResults);
  }
}
Clément Renaud
źródło
2
Czy to jest zoptymalizowane?
Argento
16

To jest przykładowy przykład, który możesz wypróbować,

var _pageNumber = 2,
  _pageSize = 50;

Student.count({},function(err,count){
  Student.find({}, null, {
    sort: {
      Name: 1
    }
  }).skip(_pageNumber > 0 ? ((_pageNumber - 1) * _pageSize) : 0).limit(_pageSize).exec(function(err, docs) {
    if (err)
      res.json(err);
    else
      res.json({
        "TotalCount": count,
        "_Array": docs
      });
  });
 });
Libu Mathew
źródło
11

Spróbuj użyć funkcji mangusty do paginacji. Limit to liczba rekordów na stronę i liczba stron.

var limit = parseInt(body.limit);
var skip = (parseInt(body.page)-1) * parseInt(limit);

 db.Rankings.find({})
            .sort('-id')
            .limit(limit)
            .skip(skip)
            .exec(function(err,wins){
 });
PayPal_Kartik
źródło
10

Tak zrobiłem na kodzie

var paginate = 20;
var page = pageNumber;
MySchema.find({}).sort('mykey', 1).skip((pageNumber-1)*paginate).limit(paginate)
    .exec(function(err, result) {
        // Write some stuff here
    });

Tak to zrobiłem.

Indra Santosa
źródło
1
Jak uzyskać całkowitą liczbę stron
Rhushikesh
Cześć @Rhushikesh, Możesz użyć funkcji count (), aby uzyskać liczbę. Ale wydaje się, że musi to być kolejne zapytanie z bazy danych. Szczegóły tutaj mongoosejs.com/docs/api.html#model_Model.count
Indra Santosa
@Rhushikesh zlicza i dzieli go przez limit
edthethird
count()jest przestarzałe. użyciecountDocuments()
Ruslan
7

Pytanie;
szukaj = nazwa produktu,

Params;
strona = 1

// Pagination
router.get("/search/:page", (req, res, next) => {
  const resultsPerPage = 5;
  const page = req.params.page >= 1 ? req.params.page : 1;
  const query = req.query.search;

  Product.find({ name: query })
    .select("name")
    .sort({ name: "asc" })
    .limit(resultsPerPage)
    .skip(resultsPerPage * page)
    .then((results) => {
      return res.status(200).send(results);
    })
    .catch((err) => {
      return res.status(500).send(err);
    });
});
Jacob Benaim
źródło
Dzięki za tę odpowiedź; Najpierw spróbowałem po przeczytaniu wątku, ponieważ był to jeden z najnowszych. Jednak kiedy go zaimplementowałem, odkryłem błąd - jak już jest napisane, nigdy nie zwróci pierwszej strony wyników, ponieważ ZAWSZE będzie miał wartość pominięcia. Spróbuj dodać „page = page-1” przed wywołaniem Product.find ().
Interog
6

Oto wersja, którą dołączam do wszystkich moich modeli. Zależy to od podkreślenia dla wygody i asynchronizacji wydajności. Opcja umożliwia wybór pola i sortowanie przy użyciu składni mangusty.

var _ = require('underscore');
var async = require('async');

function findPaginated(filter, opts, cb) {
  var defaults = {skip : 0, limit : 10};
  opts = _.extend({}, defaults, opts);

  filter = _.extend({}, filter);

  var cntQry = this.find(filter);
  var qry = this.find(filter);

  if (opts.sort) {
    qry = qry.sort(opts.sort);
  }
  if (opts.fields) {
    qry = qry.select(opts.fields);
  }

  qry = qry.limit(opts.limit).skip(opts.skip);

  async.parallel(
    [
      function (cb) {
        cntQry.count(cb);
      },
      function (cb) {
        qry.exec(cb);
      }
    ],
    function (err, results) {
      if (err) return cb(err);
      var count = 0, ret = [];

      _.each(results, function (r) {
        if (typeof(r) == 'number') {
          count = r;
        } else if (typeof(r) != 'number') {
          ret = r;
        }
      });

      cb(null, {totalCount : count, results : ret});
    }
  );

  return qry;
}

Dołącz go do schematu modelu.

MySchema.statics.findPaginated = findPaginated;
kberg
źródło
5

Powyższa odpowiedź jest dobra.

Po prostu dodatek dla każdego, kto jest w asynchronizmie, zamiast oczekiwać, że obiecuje !!

const findAllFoo = async (req, resp, next) => {
    const pageSize = 10;
    const currentPage = 1;

    try {
        const foos = await FooModel.find() // find all documents
            .skip(pageSize * (currentPage - 1)) // we will not retrieve all records, but will skip first 'n' records
            .limit(pageSize); // will limit/restrict the number of records to display

        const numberOfFoos = await FooModel.countDocuments(); // count the number of records for that model

        resp.setHeader('max-records', numberOfFoos);
        resp.status(200).json(foos);

    } catch (err) {
        resp.status(500).json({
            message: err
        });
    }
};
Sabunkar Tejas Sahailesh
źródło
5

Proste i wydajne rozwiązanie do paginacji

async getNextDocs(no_of_docs_required: number, last_doc_id?: string) {
    let docs

    if (!last_doc_id) {
        // get first 5 docs
        docs = await MySchema.find().sort({ _id: -1 }).limit(no_of_docs_required)
    }
    else {
        // get next 5 docs according to that last document id
        docs = await MySchema.find({_id: {$lt: last_doc_id}})
                                    .sort({ _id: -1 }).limit(no_of_docs_required)
    }
    return docs
}

last_doc_id: ostatni otrzymany identyfikator dokumentu

no_of_docs_required: liczba dokumentów, które chcesz pobrać, tj. 5, 10, 50 itd.

  1. Jeśli nie podasz last_doc_idmetody, otrzymasz np. 5 najnowszych dokumentów
  2. Jeśli je dostarczysz last_doc_id, otrzymasz kolejne, tj. 5 dokumentów.
WasiF
źródło
4

możesz również użyć następującego wiersza kodu

per_page = parseInt(req.query.per_page) || 10
page_no = parseInt(req.query.page_no) || 1
var pagination = {
  limit: per_page ,
  skip:per_page * (page_no - 1)
}
users = await User.find({<CONDITION>}).limit(pagination.limit).skip(pagination.skip).exec()

ten kod będzie działał w najnowszej wersji Mongo

Apoorv
źródło
3

Solidnym podejściem do realizacji tego byłoby przekazanie wartości z interfejsu użytkownika za pomocą ciągu zapytania . Powiedzmy, że chcemy uzyskać stronę 2, a także ograniczyć wynik do 25 wyników .
Ciąg zapytania wyglądałby następująco:?page=2&limit=25 // this would be added onto your URL: http:localhost:5000?page=2&limit=25

Zobaczmy kod:

// We would receive the values with req.query.<<valueName>>  => e.g. req.query.page
// Since it would be a String we need to convert it to a Number in order to do our
// necessary calculations. Let's do it using the parseInt() method and let's also provide some default values:

  const page = parseInt(req.query.page, 10) || 1; // getting the 'page' value
  const limit = parseInt(req.query.limit, 10) || 25; // getting the 'limit' value
  const startIndex = (page - 1) * limit; // this is how we would calculate the start index aka the SKIP value
  const endIndex = page * limit; // this is how we would calculate the end index

// We also need the 'total' and we can get it easily using the Mongoose built-in **countDocuments** method
  const total = await <<modelName>>.countDocuments();

// skip() will return a certain number of results after a certain number of documents.
// limit() is used to specify the maximum number of results to be returned.

// Let's assume that both are set (if that's not the case, the default value will be used for)

  query = query.skip(startIndex).limit(limit);

  // Executing the query
  const results = await query;

  // Pagination result 
 // Let's now prepare an object for the frontend
  const pagination = {};

// If the endIndex is smaller than the total number of documents, we have a next page
  if (endIndex < total) {
    pagination.next = {
      page: page + 1,
      limit
    };
  }

// If the startIndex is greater than 0, we have a previous page
  if (startIndex > 0) {
    pagination.prev = {
      page: page - 1,
      limit
    };
  }

 // Implementing some final touches and making a successful response (Express.js)

const advancedResults = {
    success: true,
    count: results.length,
    pagination,
    data: results
 }
// That's it. All we have to do now is send the `results` to the frontend.
 res.status(200).json(advancedResults);

Sugeruję zaimplementowanie tej logiki w oprogramowaniu pośrednim, abyś mógł używać jej do różnych tras / kontrolerów.

Dzenis H.
źródło
2

Najłatwiejszym i szybszym sposobem jest paginowanie za pomocą obiektu objectId Przykład;

Początkowy stan obciążenia

condition = {limit:12, type:""};

Weź pierwszy i ostatni ObjectId z danych odpowiedzi

Strona następny warunek

condition = {limit:12, type:"next", firstId:"57762a4c875adce3c38c662d", lastId:"57762a4c875adce3c38c6615"};

Strona następny warunek

condition = {limit:12, type:"next", firstId:"57762a4c875adce3c38c6645", lastId:"57762a4c875adce3c38c6675"};

W mangusty

var condition = {};
    var sort = { _id: 1 };
    if (req.body.type == "next") {
        condition._id = { $gt: req.body.lastId };
    } else if (req.body.type == "prev") {
        sort = { _id: -1 };
        condition._id = { $lt: req.body.firstId };
    }

var query = Model.find(condition, {}, { sort: sort }).limit(req.body.limit);

query.exec(function(err, properties) {
        return res.json({ "result": result);
});
byteC0de
źródło
2

Najlepszym podejściem (IMO) jest stosowanie pomijania i ograniczania ALE w ramach ograniczonych zbiorów lub dokumentów.

Aby wykonać zapytanie w ramach ograniczonych dokumentów, możemy użyć określonego indeksu, takiego jak indeks w polu typu DATA. Zobacz to poniżej

let page = ctx.request.body.page || 1
let size = ctx.request.body.size || 10
let DATE_FROM = ctx.request.body.date_from
let DATE_TO = ctx.request.body.date_to

var start = (parseInt(page) - 1) * parseInt(size)

let result = await Model.find({ created_at: { $lte: DATE_FROM, $gte: DATE_TO } })
    .sort({ _id: -1 })
    .select('<fields>')
    .skip( start )
    .limit( size )        
    .exec(callback)
Nazmul Hassan
źródło
2

Najłatwiejsza wtyczka do paginacji.

https://www.npmjs.com/package/mongoose-paginate-v2

Dodaj wtyczkę do schematu, a następnie użyj metody modelowania stronicowania:

var mongoose         = require('mongoose');
var mongoosePaginate = require('mongoose-paginate-v2');

var mySchema = new mongoose.Schema({ 
    /* your schema definition */ 
});

mySchema.plugin(mongoosePaginate);

var myModel = mongoose.model('SampleModel',  mySchema); 

myModel.paginate().then({}) // Usage
Arv Ot
źródło
ta wtyczka jest zepsuta z mangustą v.5.5.5
Isaac Pak
1

Jest to przykładowa funkcja uzyskiwania wyniku modelu umiejętności z paginacją i opcjami limitów

 export function get_skills(req, res){
     console.log('get_skills');
     var page = req.body.page; // 1 or 2
     var size = req.body.size; // 5 or 10 per page
     var query = {};
     if(page < 0 || page === 0)
     {
        result = {'status': 401,'message':'invalid page number,should start with 1'};
        return res.json(result);
     }
     query.skip = size * (page - 1)
     query.limit = size
     Skills.count({},function(err1,tot_count){ //to get the total count of skills
      if(err1)
      {
         res.json({
            status: 401,
            message:'something went wrong!',
            err: err,
         })
      }
      else 
      {
         Skills.find({},{},query).sort({'name':1}).exec(function(err,skill_doc){
             if(!err)
             {
                 res.json({
                     status: 200,
                     message:'Skills list',
                     data: data,
                     tot_count: tot_count,
                 })
             }
             else
             {
                 res.json({
                      status: 401,
                      message: 'something went wrong',
                      err: err
                 })
             }
        }) //Skills.find end
    }
 });//Skills.count end

}

Venkatesh Somu
źródło
0

Możesz napisać zapytanie w ten sposób.

mySchema.find().skip((page-1)*per_page).limit(per_page).exec(function(err, articles) {
        if (err) {
            return res.status(400).send({
                message: err
            });
        } else {
            res.json(articles);
        }
    });

strona: numer strony pochodzący od klienta jako parametry żądania.
na_stronę: liczba wyników wyświetlanych na stronie

Jeśli używasz stosu MEAN, następujący post na blogu zawiera wiele informacji na temat tworzenia stronicowania w interfejsie użytkownika za pomocą bootstrapu z angular-UI i metod pomijania i limitowania w backendu.

patrz: https://techpituwa.wordpress.com/2015/06/06/mean-js-pagination-with-angular-ui-bootstrap/

Manoj Sanjeewa
źródło
0

Możesz użyć skip () i limit (), ale jest to bardzo nieefektywne. Lepszym rozwiązaniem byłoby sortowanie według pola indeksowanego plus limit (). My w Wunderflats opublikowaliśmy małą bibliotekę tutaj: https://github.com/wunderflats/goosepage Używa pierwszej metody.

Jan Hase
źródło
0

Jeśli używasz mangusty jako źródła spokojnego interfejsu API, spójrz na „ restify-mangusta ” i jej zapytania. Ma dokładnie tę wbudowaną funkcjonalność.

Każde zapytanie w kolekcji zawiera nagłówki, które są tutaj pomocne

test-01:~$ curl -s -D - localhost:3330/data?sort=-created -o /dev/null
HTTP/1.1 200 OK
link: </data?sort=-created&p=0>; rel="first", </data?sort=-created&p=1>; rel="next", </data?sort=-created&p=134715>; rel="last"
.....
Response-Time: 37

Zasadniczo otrzymujesz ogólny serwer o stosunkowo liniowym czasie ładowania zapytań do kolekcji. To niesamowite i warto na nie spojrzeć, jeśli chcesz przejść do własnej implementacji.

Sebastian Schürmann
źródło
0
app.get("/:page",(req,res)=>{
        post.find({}).then((data)=>{
            let per_page = 5;
            let num_page = Number(req.params.page);
            let max_pages = Math.ceil(data.length/per_page);
            if(num_page == 0 || num_page > max_pages){
                res.render('404');
            }else{
                let starting = per_page*(num_page-1)
                let ending = per_page+starting
                res.render('posts', {posts:data.slice(starting,ending), pages: max_pages, current_page: num_page});
            }
        });
});
jvitoroc
źródło
0
**//localhost:3000/asanas/?pageNo=1&size=3**

//requiring asanas model
const asanas = require("../models/asanas");


const fetchAllAsanasDao = () => {
    return new Promise((resolve, reject) => {

    var pageNo = parseInt(req.query.pageNo);
    var size = parseInt(req.query.size);
    var query = {};
        if (pageNo < 0 || pageNo === 0) {
            response = {
                "error": true,
                "message": "invalid page number, should start with 1"
            };
            return res.json(response);
        }
        query.skip = size * (pageNo - 1);
        query.limit = size;

  asanas
            .find(pageNo , size , query)
        .then((asanasResult) => {
                resolve(asanasResult);
            })
            .catch((error) => {
                reject(error);
            });

    });
}
chetan
źródło
0

Użyj tej prostej wtyczki.

https://github.com/WebGangster/mongoose-paginate-v2

Instalacja

npm install mongoose-paginate-v2
Sposób użycia Dodaj wtyczkę do schematu, a następnie użyj metody modelowania stronicowania:

const mongoose         = require('mongoose');
const mongoosePaginate = require('mongoose-paginate-v2');

const mySchema = new mongoose.Schema({ 
  /* your schema definition */ 
});

mySchema.plugin(mongoosePaginate);

const myModel = mongoose.model('SampleModel',  mySchema); 

myModel.paginate().then({}) // Usage

Aravind NC
źródło
Ta wtyczka została „zasugerowana” już w innej odpowiedzi. Przydałoby się również wiedzieć, że jesteś uczestnikiem tego pakietu.
lukas_o
@lukas_o Tak. Jestem twórcą wtyczki.
Aravind NC,
0

według

Chris Hinkle

odpowiedź:

//assume every page has 50 result
const results = (req.query.page * 1) * 50;
MyModel.find( { fieldNumber: { $lte: results} })
.limit( 50 )
.sort( '+fieldNumber' )

//one thing left is create a fieldNumber on the schema thas holds ducument number
Mojtaba Hoseinpour
źródło
0

Korzystanie z ts-mongoose-pagination

    const trainers = await Trainer.paginate(
        { user: req.userId },
        {
            perPage: 3,
            page: 1,
            select: '-password, -createdAt -updatedAt -__v',
            sort: { createdAt: -1 },
        }
    )

    return res.status(200).json(trainers)
Victor Fiamoncini
źródło
0
let page,limit,skip,lastPage, query;
 page = req.params.page *1 || 1;  //This is the page,fetch from the server
 limit = req.params.limit * 1 || 1; //  This is the limit ,it also fetch from the server
 skip = (page - 1) * limit;   // Number of skip document
 lastPage = page * limit;   //last index 
 counts = await userModel.countDocuments() //Number of document in the collection

query = query.skip(skip).limit(limit) //current page

const paginate = {}

//For previous page
if(skip > 0) {
   paginate.prev = {
       page: page - 1,
       limit: limit
} 
//For next page
 if(lastPage < counts) {
  paginate.next = {
     page: page + 1,
     limit: limit
}
results = await query //Here is the final results of the query.
Hemant
źródło
-1

Był w stanie osiągnąć wyniki również asynchronicznie / czekaj.

Przykład kodu poniżej z użyciem asynchronicznego programu obsługi z hapi v17 i mongoose v5

{
            method: 'GET',
            path: '/api/v1/paintings',
            config: {
                description: 'Get all the paintings',
                tags: ['api', 'v1', 'all paintings']
            },
            handler: async (request, reply) => {
                /*
                 * Grab the querystring parameters
                 * page and limit to handle our pagination
                */
                var pageOptions = {
                    page: parseInt(request.query.page) - 1 || 0, 
                    limit: parseInt(request.query.limit) || 10
                }
                /*
                 * Apply our sort and limit
                */
               try {
                    return await Painting.find()
                        .sort({dateCreated: 1, dateModified: -1})
                        .skip(pageOptions.page * pageOptions.limit)
                        .limit(pageOptions.limit)
                        .exec();
               } catch(err) {
                   return err;
               }

            }
        }
csichar
źródło