Làm cách nào để phân trang với Mongoose trong Node.js?


232

Tôi đang viết một ứng dụng web với Node.js và mongoose. Làm cách nào tôi có thể phân trang kết quả tôi nhận được từ một .find()cuộc gọi? Tôi muốn một chức năng tương đương với "LIMIT 50,100"trong SQL.


Sử dụng bỏ qua và giới hạn thuộc tính trong khi tìm dữ liệu từ bộ sưu tập.
Arun Sahani

Liên kết này có thể được sử dụng cho bạn chi tiết. laxmanchavda.blogspot.com/2018/06/...
Laxman

Câu trả lời:


278

Tôi rất thất vọng bởi những câu trả lời được chấp nhận trong câu hỏi này. Điều này sẽ không mở rộng. Nếu bạn đọc bản in đẹp trên con trỏ.skip ():

Phương thức con trỏ.skip () thường tốn kém vì nó yêu cầu máy chủ đi bộ từ đầu bộ sưu tập hoặc chỉ mục để lấy vị trí bù hoặc bỏ qua trước khi bắt đầu trả về kết quả. Khi offset (ví dụ: số trang ở trên) tăng lên, con trỏ.skip () sẽ trở nên chậm hơn và tốn nhiều CPU hơn. Với các bộ sưu tập lớn hơn, con trỏ.skip () có thể bị ràng buộc IO.

Để đạt được phân trang theo cách có thể mở rộng, hãy kết hợp một giới hạn () cùng với ít nhất một tiêu chí bộ lọc, ngày được tạo phù hợp với nhiều mục đích.

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

105
Nhưng làm thế nào bạn có thể nhận được trang hai từ truy vấn đó mà không bỏ qua? Nếu bạn đang xem 10 kết quả trên mỗi trang và có 100 kết quả, làm thế nào để bạn xác định giá trị bù hoặc bỏ qua? Bạn không trả lời câu hỏi phân trang, vì vậy bạn không thể 'thất vọng', mặc dù đó là một sự thận trọng hợp lệ. Mặc dù vấn đề tương tự là ở phần bù của MySQL, giới hạn. Nó phải đi qua cây để bù trước khi trả kết quả. Tôi sẽ dùng nó với một hạt muối, nếu tập kết quả của bạn nhỏ hơn 1mil và không có hiệu suất có thể bảo quản, hãy sử dụng Skip ().
Lex

13
Tôi là một người mới khi nói đến mongoose / mongodb, nhưng để trả lời câu hỏi của Lex, có vẻ như , khi kết quả được sắp xếp theo ' -createdOn', bạn sẽ thay thế giá trị request.createdOnBeforebằng giá trị createdOntrả về ít nhất trong tập kết quả trước đó, và sau đó yêu cầu.
Terry Lewis

9
@JoeFrambach Yêu cầu dựa trên createdOn có vẻ có vấn đề. Skip được nhúng vì một lý do. Các tài liệu chỉ cảnh báo về hiệu suất của việc đạp xe thông qua chỉ số btree, đó là trường hợp của tất cả các DBMS. Đối với người dùng câu hỏi "một cái gì đó có thể so sánh MySQL với LIMIT 50.100" .skip hoàn toàn chính xác.
Lex

8
Mặc dù thú vị, một vấn đề với câu trả lời này, như ghi chú của @Lex, là bạn chỉ có thể bỏ qua "chuyển tiếp" hoặc "quay lại" thông qua kết quả - bạn không thể có "trang" mà bạn có thể chuyển đến (ví dụ: Trang 1, Trang 2 , Trang 3) mà không thực hiện nhiều truy vấn tuần tự để tìm ra nơi bắt đầu phân trang, điều mà tôi nghi ngờ sẽ chậm hơn trong hầu hết các trường hợp thay vì chỉ sử dụng bỏ qua. Tất nhiên bạn có thể không cần thêm khả năng bỏ qua các trang cụ thể.
Iain Collins

20
Câu trả lời này chứa những điểm thú vị, nhưng nó không trả lời câu hỏi ban đầu.
steampowered

227

Sau khi xem xét kỹ hơn về API Mongoose với thông tin được cung cấp bởi Rodolphe, tôi đã tìm ra giải pháp này:

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

21
Thế còn "tính"? Bạn cần điều đó để biết có bao nhiêu trang.
Aleksey Saatchi

36
Không quy mô.
Chris Hinkle

4
Giải thích của Chris Hinkle tại sao điều này không mở rộng: stackoverflow.com/a/23640287/165330 .
imme

7
@ChrisHinkle Điều này dường như là trường hợp của tất cả các DBMS. Bình luận của Lex bên dưới câu trả lời được liên kết dường như giải thích thêm.
csotiriou

2
@Avij vâng. Tôi đã sử dụng định danh cho điều đó. những gì bạn làm trong đó là gửi id hồ sơ cuối cùng trở lại máy chủ và nhận một số hồ sơ với id lớn hơn gửi. Vì Id được lập chỉ mục như vậy, nó sẽ nhanh hơn nhiều
George Bailey

108

Phân trang bằng cầy mangut, thể hiện và ngọc bích - Đây là một liên kết đến blog của tôi với nhiều chi tiết hơn

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
Cảm ơn đã gửi câu trả lời của bạn! Hãy chắc chắn đọc Câu hỏi thường gặp về Tự quảng cáo một cách cẩn thận. Cũng lưu ý rằng nó là cần thiết mà bạn gửi một từ chối trách nhiệm mỗi khi bạn liên kết đến trang web / sản phẩm của riêng bạn.
Andrew Barber

Math.max(0, undefined)sẽ trở lại undefined, Điều này làm việc cho tôi: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

Bạn có thể xâu chuỗi như thế:

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

Thực hiện truy vấn bằng cách sử dụng exec

query.exec(callback);

Cảm ơn câu trả lời của bạn, cuộc gọi lại với kết quả được thêm vào như thế nào?
Thomas

2
execFind (function (... ví dụ: 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
lưu ý: điều này sẽ không hoạt động trong cầy mangut , nhưng nó sẽ hoạt động trong trình điều khiển bản địa mongodb.
Jesse

39

Trong trường hợp này, bạn có thể thêm truy vấn pagevà / hoặc limitvào URL của bạn dưới dạng chuỗi truy vấn.

Ví dụ:
?page=0&limit=25 // this would be added onto your URL: http:localhost:5000?page=0&limit=25

Vì nó sẽ là một thứ Stringchúng ta cần chuyển đổi nó thành một Numbertính toán của chúng ta. Chúng ta hãy làm điều đó bằng parseIntphương pháp và cũng cung cấp một số giá trị mặc định.

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

Phân trang BTW bắt đầu bằng0


5
vui lòng thêm `{page: parseInt (req.query.page) || 0, ...} đến tham số.
imalik8088

@ imalik8088 Cảm ơn bạn, tuy nhiên thông số chuỗi AFAIK đang được xử lý tự động bởi mongoose.
CENT1PEDE

1
Đã mong đợi hành vi nhưng trong trường hợp của tôi, nó không thể bí mật và hiển thị lỗi cho tôi
imalik8088

@ imalik8088 Thật lạ. Có lẽ nếu bạn có thể hiển thị một lỗi sinh sản, tôi có thể chỉnh sửa câu trả lời của mình. Cảm ơn.
CENT1PEDE

2
Điều này sẽ khiến cầy mangut tìm thấy mọi kỷ lục trước khi áp dụng các điều kiện?
FluffyBying 23/11/18

37

Bạn có thể sử dụng một gói nhỏ gọi là Mongoose Paginate giúp dễ dàng hơn.

$ npm install mongoose-paginate

Sau khi trong tuyến đường hoặc bộ điều khiển của bạn, chỉ cần thêm:

/**
 * 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
Điều này có được tối ưu hóa không?
Argento

16

Đây là một ví dụ mẫu bạn có thể thử,

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

Hãy thử sử dụng chức năng cầy mangut để phân trang. Giới hạn là số lượng hồ sơ trên mỗi trang và số lượng trang.

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

Đây là những gì tôi đã làm nó trên mã

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

Đó là cách tôi đã làm nó.


1
Cách lấy tổng số trang không có
Rhushikesh

Xin chào @Rhushikesh, Bạn có thể sử dụng hàm Count () để lấy số đếm. Nhưng nó có vẻ cần phải là một truy vấn khác từ cơ sở dữ liệu. Chi tiết tại đây mongoosejs.com/docs/api.html#model_Model.count
Indra Santosa

@Rhushikesh lấy số đếm và chia cho giới hạn
edthethird

count()bị phản đối sử dụngcountDocuments()
Ruslan

7

Truy vấn;
tìm kiếm = tên sản phẩm,

Param;
trang = 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);
    });
});

Cảm ơn câu trả lời này; Tôi đã thử nó đầu tiên sau khi đọc qua các chủ đề bởi vì nó là một trong những cái gần đây hơn. Tuy nhiên, khi tôi thực hiện nó, tôi phát hiện ra một lỗi - vì nó được viết ngay bây giờ, nó sẽ không bao giờ trả lại trang kết quả đầu tiên, vì nó LUÔN LUÔN có giá trị bỏ qua. Hãy thử thêm "page = page-1" trước lệnh gọi Product.find ().
Interog

6

Đây là một phiên bản mà tôi đính kèm cho tất cả các mô hình của tôi. Nó phụ thuộc vào gạch dưới để thuận tiện và không đồng bộ cho hiệu suất. Các opts cho phép lựa chọn và sắp xếp trường bằng cú pháp mongoose.

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

Đính kèm nó vào lược đồ mô hình của bạn.

MySchema.statics.findPaginated = findPaginated;

6

Giải pháp phân trang đơn giản và mạnh mẽ

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 tài liệu cuối cùng mà bạn nhận được

no_of_docs_required: số lượng tài liệu mà bạn muốn tìm nạp, tức là 5, 10, 50, v.v.

  1. Nếu bạn không cung cấp last_doc_idphương thức, bạn sẽ nhận được tức là 5 tài liệu mới nhất
  2. Nếu bạn đã cung cấp last_doc_idthì bạn sẽ nhận được 5 tài liệu tiếp theo.

5

Trên câu trả lời giữ tốt.

Chỉ là một tiện ích bổ sung cho bất kỳ ai không đồng bộ - chờ đợi hơn là hứa hẹn !!

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

bạn cũng có thể sử dụng dòng mã sau

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

mã này sẽ hoạt động trong phiên bản mới nhất của mongo


3

Một cách tiếp cận vững chắc để thực hiện điều này sẽ là chuyển các giá trị từ frontend bằng chuỗi truy vấn . Giả sử chúng tôi muốn lấy trang số 2 và cũng giới hạn đầu ra ở 25 kết quả .
Chuỗi truy vấn sẽ như thế này:?page=2&limit=25 // this would be added onto your URL: http:localhost:5000?page=2&limit=25

Hãy xem mã:

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

Tôi sẽ đề nghị triển khai logic này vào phần mềm trung gian để bạn có thể sử dụng nó cho các tuyến / bộ điều khiển khác nhau.


2

Cách dễ nhất và nhanh hơn là, phân trang với Ví dụ objectId;

Điều kiện tải ban đầu

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

Lấy ObjectId đầu tiên và cuối cùng từ dữ liệu phản hồi

Trang điều kiện tiếp theo

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

Trang điều kiện tiếp theo

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

Ở cầy mangut

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

Cách tiếp cận tốt nhất (IMO) là sử dụng bỏ qua và giới hạn NHƯNG trong một bộ sưu tập hoặc tài liệu giới hạn.

Để thực hiện truy vấn trong các tài liệu giới hạn, chúng ta có thể sử dụng chỉ mục cụ thể như chỉ mục trên trường loại DATE. Xem bên dưới

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 dễ nhất cho phân trang.

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

Thêm plugin vào một lược đồ và sau đó sử dụng phương pháp phân trang mô hình:

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 này bị hỏng với mongoose v5.5.5
Isaac Pak

1

Đây là chức năng ví dụ để nhận kết quả của mô hình kỹ năng với các tùy chọn phân trang và giới hạn

 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

Bạn có thể viết truy vấn như thế này.

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

trang: số trang đến từ khách hàng như tham số yêu cầu.
per_page: không có kết quả nào được hiển thị trên mỗi trang

Nếu bạn đang sử dụng MEAN stack theo bài đăng trên blog, sẽ cung cấp nhiều thông tin để tạo phân trang ở giao diện người dùng bằng cách sử dụng bootstrap góc và sử dụng phương pháp bỏ qua và giới hạn mongoose trong phần phụ trợ.

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


0

Bạn có thể sử dụng Skip () và giới hạn (), nhưng nó rất không hiệu quả. Một giải pháp tốt hơn sẽ là sắp xếp trên trường được lập chỉ mục cộng với giới hạn (). Chúng tôi tại Wunderflats đã xuất bản một lib nhỏ ở đây: https://github.com/wunderflats/goosepage Nó sử dụng cách đầu tiên.


0

Nếu bạn đang sử dụng cầy mangut làm nguồn cho một api yên tĩnh, hãy xem ' restify-mongoose ' và các truy vấn của nó. Nó có chính xác chức năng này được xây dựng trong.

Bất kỳ truy vấn nào trên bộ sưu tập đều cung cấp các tiêu đề hữu ích ở đây

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

Vì vậy, về cơ bản, bạn nhận được một máy chủ chung với thời gian tải tương đối tuyến tính cho các truy vấn đến bộ sưu tập. Đó là điều tuyệt vời và một cái gì đó để xem xét nếu bạn muốn đi vào thực hiện riêng.


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

Sử dụng plugin đơn giản này.

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

Cài đặt

npm install mongoose-paginate-v2
Sử dụng Thêm plugin vào một lược đồ và sau đó sử dụng phương pháp phân trang mô hình:

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 này đã được "gợi ý" trong câu trả lời khác. Nó cũng sẽ hữu ích để biết rằng bạn nếu là một người đóng góp cho gói này.
lukas_o

@lukas_o Vâng. Tôi là người tạo ra plugin.
Aravind NC

0

dựa theo

Chris Hinkle

câu trả lời:

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

Sử dụng 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)

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

Đã có thể đạt được kết quả với async / await.

Ví dụ mã dưới đây bằng trình xử lý async với hapi v17 và 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;
               }

            }
        }
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.