Bagaimana cara memberi nomor dengan Mongoose di Node.js?


232

Saya menulis webapp dengan Node.js dan luwak. Bagaimana saya bisa memberi nomor hasil yang saya dapatkan dari .find()panggilan telepon? Saya ingin fungsionalitas yang sebanding dengan "LIMIT 50,100"di SQL.


Gunakan lewati dan batasi properti saat mencari data dari koleksi.
Arun Sahani

Tautan ini dapat digunakan untuk Anda secara detail. laxmanchavda.blogspot.com/2018/06/...
laxman

Jawaban:


278

Saya sangat kecewa dengan jawaban yang diterima dalam pertanyaan ini. Ini tidak akan skala. Jika Anda membaca tulisan kecil di cursor.skip ():

Metode cursor.skip () seringkali mahal karena mengharuskan server berjalan dari awal koleksi atau indeks untuk mendapatkan posisi offset atau lompati sebelum mulai mengembalikan hasil. Saat offset (mis. PageNumber di atas) meningkat, cursor.skip () akan menjadi lebih lambat dan lebih intensif CPU. Dengan koleksi yang lebih besar, cursor.skip () dapat menjadi terikat IO.

Untuk mencapai pagination dengan cara yang dapat dikombinasi, gabungkan batas () bersama dengan setidaknya satu kriteria filter, tanggal yang dibuat sesuai dengan banyak tujuan.

MyModel.find( { createdOn: { $lte: request.createdOnBefore } } )
.limit( 10 )
.sort( '-createdOn' )

105
Tetapi bagaimana Anda mendapatkan halaman dua dari permintaan itu tanpa melewati? Jika Anda melihat 10 hasil per halaman, dan ada 100 hasil, bagaimana Anda kemudian menentukan nilai offset atau lewati? Anda tidak menjawab pertanyaan pagination, jadi Anda tidak bisa 'kecewa', meskipun itu adalah kehati-hatian yang valid. Meskipun masalah yang sama ada di MySQL offset, batasi. Itu harus melintasi pohon ke offset sebelum mengembalikan hasil. Saya akan mengambil ini dengan sebutir garam, jika set hasil Anda kurang dari 1mil dan tidak ada hit kinerja yang dapat dipertahankan, gunakan skip ().
Lex

13
Saya seorang noob ketika datang ke luwak / mongodb, tetapi untuk menjawab pertanyaan Lex, tampaknya , karena hasilnya dipesan oleh ' -createdOn', Anda akan mengganti nilai request.createdOnBeforedengan nilai paling sedikit dari createdOnpengembalian di set hasil sebelumnya, dan kemudian meminta kembali.
Terry Lewis

9
@JoeFrambach Meminta berdasarkan CreatedOn tampaknya bermasalah. Lewati telah disematkan karena suatu alasan. Docs hanya memperingatkan kinerja hit bersepeda melalui indeks btree, yang merupakan kasus dengan semua DBMS. Untuk pertanyaan pengguna "MySQL sesuatu yang sebanding dengan LIMIT 50.100" .skip tepat.
Lex

8
Meskipun menarik, masalah dengan jawaban ini, seperti catatan komentar @Lex, adalah bahwa Anda hanya dapat melewati "maju" atau "kembali" melalui hasil - Anda tidak dapat memiliki "halaman" yang dapat Anda lompati (mis. Halaman 1, Halaman 2 , Halaman 3) tanpa membuat beberapa kueri berurutan untuk menentukan dari mana memulai pagination, yang saya duga akan lebih lambat dalam banyak kasus daripada hanya menggunakan skip. Tentu saja Anda mungkin tidak perlu menambahkan kemampuan untuk melompat ke halaman tertentu.
Iain Collins

20
Jawaban ini mengandung poin menarik, tetapi tidak menjawab pertanyaan awal yang diajukan.
dikemudikan

227

Setelah melihat lebih dekat pada API Mongoose dengan informasi yang diberikan oleh Rodolphe, saya menemukan solusi ini:

MyModel.find(query, fields, { skip: 10, limit: 5 }, function(err, results) { ... });

21
Bagaimana dengan "menghitung"? Anda memerlukannya untuk mengetahui berapa banyak halaman yang ada.
Aleksey Saatchi

36
Tidak berskala.
Chris Hinkle

4
Penjelasan Chris Hinkle mengapa ini tidak skala: stackoverflow.com/a/23640287/165330 .
Imme

7
@ ChrisHinkle Tampaknya ini adalah kasus dengan semua DBMS. Komentar Lex di bawah jawaban yang terhubung tampaknya menjelaskan lebih banyak.
csotiriou

2
@Vij ya. Saya telah menggunakan pengenal untuk itu. apa yang Anda lakukan di sana adalah mengirim id catatan terakhir kembali ke server dan mendapatkan beberapa catatan dengan id lebih besar dari yang dikirim. Ketika Id diindeks demikian, itu akan jauh lebih cepat
George Bailey

108

Pagination menggunakan luwak, express, dan jade - Inilah tautan ke blog saya dengan lebih detail

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

26
Terima kasih telah mengirim jawaban Anda! Pastikan untuk membaca FAQ tentang Promosi Diri dengan cermat. Juga mencatat bahwa itu diperlukan bahwa Anda memasukkan disclaimer setiap kali Anda link ke situs Anda sendiri / produk.
Andrew Barber

Math.max(0, undefined)akan kembali undefined, Ini bekerja untuk saya: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

Anda dapat rantai seperti itu:

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

Jalankan permintaan menggunakan exec

query.exec(callback);

Terima kasih atas jawaban Anda, bagaimana panggilan balik dengan hasil ditambahkan ke ini?
Thomas

2
execFind (fungsi (... misalnya: 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
Catatan: ini tidak akan bekerja di luwak , tetapi akan bekerja di driver Mongong-asli.
Jesse

39

Dalam hal ini, Anda dapat menambahkan kueri pagedan / atau limitke URL Anda sebagai string kueri.

Sebagai contoh:
?page=0&limit=25 // this would be added onto your URL: http:localhost:5000?page=0&limit=25

Karena itu akan menjadi, Stringkita perlu mengubahnya menjadi Numberuntuk perhitungan kita. Mari kita lakukan dengan menggunakan parseIntmetode dan mari kita juga memberikan beberapa nilai default.

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 Pagination dimulai dengan0


5
silakan tambahkan `{halaman: parseInt (req.query.page) || 0, ...} ke parameter.
imalik8088

@ imalik8088 Terima kasih, namun string string AFAIK sedang ditangani secara otomatis oleh mongoose.
CENT1PEDE

1
Mengharapkan perilaku tetapi dalam kasus saya itu tidak bisa terselubung dan menunjukkan saya kesalahan
imalik8088

@ imalik8088 Aneh. Mungkin jika Anda dapat menampilkan kesalahan reproduksi, saya dapat mengedit jawaban saya. Terima kasih.
CENT1PEDE

2
Apakah ini menyebabkan luwak menemukan setiap rekaman sebelum menerapkan persyaratan?
FluffyBeing

37

Anda dapat menggunakan paket kecil yang disebut Mongoose Paginate yang membuatnya lebih mudah.

$ npm install mongoose-paginate

Setelah di rute atau pengontrol Anda, cukup tambahkan:

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

2
Apakah ini dioptimalkan?
Argento

16

Ini adalah contoh contoh yang dapat Anda coba ini,

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

11

Coba gunakan fungsi luwak untuk pagination. Batas adalah jumlah catatan per halaman dan jumlah halaman.

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

10

Inilah yang saya lakukan pada kode

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

Begitulah cara saya melakukannya.


1
Cara mendapatkan no total halaman
Rhushikesh

Hai @Rhushikesh, Anda dapat menggunakan fungsi count () untuk mendapatkan hitungan. Tapi sepertinya perlu query lain dari database. Detail di sini mongoosejs.com/docs/api.html#model_Model.count
Indra Santosa

@Rhushikesh mendapatkan hitungan dan membaginya dengan batas
edthethird

count()sudah ditinggalkan. gunakancountDocuments()
Ruslan

7

Pertanyaan;
search = productName,

Params;
halaman = 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);
    });
});

Terima kasih atas jawaban ini; Saya mencobanya terlebih dahulu setelah membaca utas karena itu salah satu yang lebih baru. Namun, ketika saya menerapkannya, saya menemukan bug - seperti yang tertulis sekarang, itu tidak akan pernah mengembalikan halaman hasil pertama, karena SELALU akan SELALU memiliki nilai lewati. Coba tambahkan "halaman = halaman-1" sebelum panggilan Product.find ().
Interog

6

Ini adalah versi yang saya lampirkan ke semua model saya. Itu tergantung pada garis bawah untuk kenyamanan dan async untuk kinerja. Pilihan memungkinkan untuk pemilihan bidang dan penyortiran menggunakan sintaks luwak.

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

Lampirkan ke skema model Anda.

MySchema.statics.findPaginated = findPaginated;

6

Solusi pagination sederhana dan kuat

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: id dokumen terakhir yang Anda dapatkan

no_of_docs_required: jumlah dokumen yang ingin Anda ambil yaitu 5, 10, 50 dll.

  1. Jika Anda tidak memberikan last_doc_idmetode tersebut, Anda akan mendapatkan 5 dokumen terbaru
  2. Jika Anda telah menyediakan last_doc_idmaka Anda akan mendapatkan 5 dokumen berikutnya yaitu.

5

Jawaban di atas bagus.

Hanya add-on untuk siapa saja yang async-tunggu daripada janji !!

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

4

Anda dapat menggunakan baris kode berikut juga

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()

kode ini akan berfungsi dalam versi mongo terbaru


3

Pendekatan yang solid untuk mengimplementasikan ini adalah untuk melewatkan nilai-nilai dari frontend menggunakan string kueri . Katakanlah kita ingin mendapatkan halaman # 2 dan juga membatasi output hingga 25 hasil .
String kueri akan terlihat seperti ini:?page=2&limit=25 // this would be added onto your URL: http:localhost:5000?page=2&limit=25

Mari kita lihat kodenya:

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

Saya akan menyarankan mengimplementasikan logika ini ke middleware sehingga Anda dapat menggunakannya untuk berbagai rute / pengontrol.


2

Cara termudah dan lebih cepat adalah, paginasi dengan objectId Contoh;

Kondisi muatan awal

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

Ambil ObjectId pertama dan terakhir dari data respons

Halaman kondisi selanjutnya

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

Halaman kondisi selanjutnya

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

Pada luwak

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

2

Pendekatan terbaik (IMO) adalah menggunakan lewati dan batasi BUT dalam koleksi atau dokumen terbatas.

Untuk membuat kueri dalam dokumen terbatas, kita bisa menggunakan indeks seperti indeks tertentu pada bidang tipe DATE. Lihat itu di bawah

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)

2

Plugin paling mudah untuk pagination.

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

Tambahkan plugin ke skema dan kemudian gunakan metode model paginate:

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

plugin ini rusak dengan luong v5.5.5
Isaac Pak

1

Ini adalah contoh fungsi untuk mendapatkan hasil model keterampilan dengan opsi pagination dan limit

 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

}


0

Anda dapat menulis kueri seperti ini.

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

halaman: nomor halaman yang berasal dari klien sebagai parameter permintaan.
per_page: tidak ada hasil yang ditampilkan per halaman

Jika Anda menggunakan tumpukan MEAN setelah posting blog menyediakan banyak informasi untuk membuat pagination di ujung depan menggunakan bootstrap sudut-UI dan menggunakan metode lompat jauh dan batas luak di backend.

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


0

Anda dapat menggunakan skip () dan limit (), tetapi sangat tidak efisien. Solusi yang lebih baik akan menjadi semacam bidang diindeks plus batas (). Kami di Wunderflats telah menerbitkan lib kecil di sini: https://github.com/wunderflats/goosepage Ini menggunakan cara pertama.


0

Jika Anda menggunakan luwak sebagai sumber api yang nyenyak, lihat ' restify-luwak' ' dan pertanyaannya. Ini persis memiliki fungsi ini bawaan.

Setiap kueri pada koleksi memberikan tajuk yang bermanfaat di sini

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

Jadi pada dasarnya Anda mendapatkan server generik dengan waktu buka yang relatif linier untuk kueri ke koleksi. Itu luar biasa dan sesuatu untuk dilihat jika Anda ingin pergi ke implementasi sendiri.


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

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

    });
}

0

Gunakan plugin sederhana ini.

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

Instalasi

npm install mongoose-paginate-v2
Penggunaan Tambahkan plugin ke skema dan kemudian gunakan metode model paginate:

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


Plugin ini sudah "disarankan" di jawaban lain. Akan sangat membantu untuk mengetahui bahwa Anda adalah kontributor pada paket ini.
lukas_o

@lukas_o Ya. Saya pencipta plugin.
Aravind NC

0

berdasarkan

Chris Hinkle

menjawab:

//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

0

Menggunakan ts-luwak-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)

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.

-1

Mampu mencapai hasil dengan async / menunggu juga.

Contoh kode di bawah ini menggunakan async handler dengan hapi v17 dan luoose 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;
               }

            }
        }
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.