diff --git a/README.md b/README.md index 257a937..ddaf918 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ This plugin must first be added to a schema: ```js -var mongooseAggregatePaginate = require('mongoose-aggregate-paginate'); +let mongooseAggregatePaginate = require('mongoose-aggregate-paginate'); mySchema.plugin(mongooseAggregatePaginate); @@ -43,8 +43,8 @@ mySchema.plugin(mongooseAggregatePaginate); * `options` - An object with options for the [Mongoose][mongoose] query, such as sorting - `page` - Default: `1` - `limit` - Default: `10` - - `sortBy` - Default: `undefined` -* `callback(err, results, pageCount, itemCount)` - A callback is called once pagination results are retrieved, or an error has occurred. If not specified promise will be returned + - `sort` - Default: `undefined` +* `callback(err, results, pages, total)` - A callback is called once pagination results are retrieved, or an error has occurred. If not specified promise will be returned **Returns** * `Promise` - Promise object @@ -53,20 +53,20 @@ mySchema.plugin(mongooseAggregatePaginate); ```js -var MyModel = mongoose.model('MyModel',{ +let MyModel = mongoose.model('MyModel',{ name : String, age: Number, city, String }) // find users above 18 by city -var aggregate = MyModel.aggregate(); +let aggregate = MyModel.aggregate(); aggregate.match({age : {'lt' : 18 } }) .group({ _id: '$city' , count : { '$sum' : 1 } }) -var options = { page : 1, limit : 15} +let options = { page : 1, limit : 15} // callback -MyModel.aggregatePaginate(aggregate, options, function(err, results, pageCount, count) { +MyModel.aggregatePaginate(aggregate, options, function(err, results, pages, count) { if(err) { console.err(err) @@ -80,7 +80,7 @@ MyModel.aggregatePaginate(aggregate, options, function(err, results, pageCount, // Promise MyModel.aggregatePaginate(aggregate, options) .then(function(value) { - console.log(value.data, value.pageCount, value.totalCount) + console.log(value.docs, value.pages, value.total) }) .catch(function(err){ console.err(err) diff --git a/lib/mongoose-aggregate-paginate.js b/lib/mongoose-aggregate-paginate.js index 931be5e..319ca3a 100644 --- a/lib/mongoose-aggregate-paginate.js +++ b/lib/mongoose-aggregate-paginate.js @@ -3,38 +3,46 @@ /** * Paginate Mongoose aggregate result * @param {Aggregate} aggregate - * @param {any} options {page: number/string default 10, limit: number/string default 10,sortBy: any default null} + * @param {any} options {page: number/string default 10, limit: number/string default 10,sort: any default null} * @param {function} [callback] * @returns {Promise} */ function aggregatePaginate (aggregate, options, callback) { options = options || {} - var pageNumber = parseInt(options.page || 1, 10) - var resultsPerPage = parseInt(options.limit || 10, 10) - var skipDocuments = (pageNumber - 1) * resultsPerPage - var sortBy = options.sortBy + let pageNumber = parseInt(options.page || 1, 10) + let resultsPerPage = parseInt(options.limit || 10, 10) + let skipDocuments = (pageNumber - 1) * resultsPerPage + let sort = options.sort - var q = this.aggregate(aggregate._pipeline) - var countQuery = this.aggregate(q._pipeline) + let q = this.aggregate(aggregate._pipeline) + let countQuery = this.aggregate(q._pipeline) if (q.hasOwnProperty('options')) { q.options = aggregate.options countQuery.options = aggregate.options } - if (sortBy) { - q.sort(sortBy) + if (sort) { + q.sort(sort) } - return Promise.all([q.skip(skipDocuments).limit(resultsPerPage).exec(), countQuery.group({ _id: null, count: { $sum: 1 } }).exec()]) + return Promise.all([ + q.skip(skipDocuments).limit(resultsPerPage).exec(), + countQuery.group({ + _id: null, + count: {$sum: 1} + }).exec() + ]) .then(function (values) { - var count = values[1][0] ? values[1][0].count : 0 + let count = values[1][0] ? values[1][0].count : 0 if (typeof callback === 'function') { return callback(null, values[0], Math.ceil(count / resultsPerPage) || 1, values[1][0] ? count : 0) } return Promise.resolve({ - data: values[0], - pageCount: (Math.ceil(count / resultsPerPage) || 1), - totalCount: count + docs: values[0], + total: count, + limit: resultsPerPage, + page: pageNumber, + pages: (Math.ceil(count / resultsPerPage) || 1) }) }) .catch(function (reject) { diff --git a/test/all.tests.js b/test/all.tests.js index 513e528..c3b40d4 100644 --- a/test/all.tests.js +++ b/test/all.tests.js @@ -8,17 +8,18 @@ var Schema = mongoose.Schema mongoose.Promise = Promise /** -* test Schema -*/ -var testSchema = new Schema({ - studentId: Number, - marksheet: [{ - subject: String, - marks: Number - }] -}, + * test Schema + */ +var testSchema = new Schema( { - timestamps: { createdAt: 'created', updatedAt: 'modified' } + studentId: Number, + marksheet: [{ + subject: String, + marks: Number + }] + }, + { + timestamps: {createdAt: 'created', updatedAt: 'modified'} } ) testSchema.plugin(mongooseAggregatePaginate) @@ -31,7 +32,13 @@ describe('Mongoose Aggregate Paginate tests', function () { before(function (done) { var testData = [] for (var index = 0; index < 100; ++index) { - testData.push(new TestModel({ studentId: index, marksheet: [{ subject: 'physics', marks: 100 - (index % 9) }, { subject: 'math', marks: 100 - (index % 8) }, { subject: 'chem', marks: 100 - (index % 7) }] })) + testData.push(new TestModel({ + studentId: index, + marksheet: [{subject: 'physics', marks: 100 - (index % 9)}, { + subject: 'math', + marks: 100 - (index % 8) + }, {subject: 'chem', marks: 100 - (index % 7)}] + })) } Promise.all([TestModel.remove({}), TestModel.create(testData)]) .then(function () { done() }) @@ -45,16 +52,16 @@ describe('Mongoose Aggregate Paginate tests', function () { describe('Basic Tests on 100 documents', function () { var query = TestModel.aggregate().allowDiskUse(true) - .project({ 'marksheet': 1, 'studentId': 1 }) + .project({'marksheet': 1, 'studentId': 1}) .unwind('$marksheet') - .group({ _id: '$studentId', total: { $sum: '$marksheet.marks' } }) + .group({_id: '$studentId', total: {$sum: '$marksheet.marks'}}) describe('without page and limit (callback)', function () { it('should return 10 results, page count = 10 and total count = 100', function (done) { - TestModel.aggregatePaginate(query, {}, function (err, result, pageCount, totalCount) { + TestModel.aggregatePaginate(query, {}, function (err, result, pages, total) { if (err) return done(err) result.length.should.equal(10) - pageCount.should.equal(10) - totalCount.should.equal(100) + pages.should.equal(10) + total.should.equal(100) done() }) }) @@ -64,9 +71,9 @@ describe('Mongoose Aggregate Paginate tests', function () { it('should return 10 results, page count = 10 and total count = 100', function (done) { TestModel.aggregatePaginate(query, {}) .then(function (value) { - value.data.length.should.equal(10) - value.pageCount.should.equal(10) - value.totalCount.should.equal(100) + value.docs.length.should.equal(10) + value.pages.should.equal(10) + value.total.should.equal(100) done() }) .catch(done) @@ -75,11 +82,11 @@ describe('Mongoose Aggregate Paginate tests', function () { describe('without page and limit using undefined as options param (callback)', function () { it('should return 10 results, page count = 10 and total count = 100', function (done) { - TestModel.aggregatePaginate(query, undefined, function (err, result, pageCount, totalCount) { + TestModel.aggregatePaginate(query, undefined, function (err, result, pages, total) { if (err) return done(err) result.length.should.equal(10) - pageCount.should.equal(10) - totalCount.should.equal(100) + pages.should.equal(10) + total.should.equal(100) done() }) }) @@ -89,9 +96,9 @@ describe('Mongoose Aggregate Paginate tests', function () { it('should return 10 results, page count = 10 and total count = 100', function (done) { TestModel.aggregatePaginate(query, undefined) .then(function (value) { - value.data.length.should.equal(10) - value.pageCount.should.equal(10) - value.totalCount.should.equal(100) + value.docs.length.should.equal(10) + value.pages.should.equal(10) + value.total.should.equal(100) done() }) .catch(done) @@ -100,52 +107,56 @@ describe('Mongoose Aggregate Paginate tests', function () { describe('with limit (callback)', function () { it('should return 20 results, page count = 5 and total count = 100 when limit is 20', function (done) { - TestModel.aggregatePaginate(query, { limit: 20 }, function (err, result, pageCount, totalCount) { + TestModel.aggregatePaginate(query, {limit: 20}, function (err, result, pages, total) { if (err) return done(err) result.length.should.equal(20) - pageCount.should.equal(5) - totalCount.should.equal(100) + pages.should.equal(5) + total.should.equal(100) done() }) }) it('should return 5 results, page count = 20 and total count = 100 when limit is 5', function (done) { - TestModel.aggregatePaginate(query, { limit: 5 }, function (err, result, pageCount, totalCount) { + TestModel.aggregatePaginate(query, {limit: 5}, function (err, result, pages, total) { if (err) return done(err) result.length.should.equal(5) - pageCount.should.equal(20) - totalCount.should.equal(100) + pages.should.equal(20) + total.should.equal(100) done() }) }) it('should return 100 results, page count = 1 and total count = 100 when limit is 200', function (done) { - TestModel.aggregatePaginate(query, { limit: 200 }, function (err, result, pageCount, totalCount) { + TestModel.aggregatePaginate(query, {limit: 200}, function (err, result, pages, total) { if (err) return done(err) result.length.should.equal(100) - pageCount.should.equal(1) - totalCount.should.equal(100) + pages.should.equal(1) + total.should.equal(100) done() }) }) it('should return 0 results, page count = 1 and total count = 100 when limit = 200 and page = 2', function (done) { - TestModel.aggregatePaginate(query, { limit: 200, page: 2 }, function (err, result, pageCount, totalCount) { + TestModel.aggregatePaginate(query, {limit: 200, page: 2}, function (err, result, pages, total) { if (err) return done(err) result.length.should.equal(0) - pageCount.should.equal(1) - totalCount.should.equal(100) + pages.should.equal(1) + total.should.equal(100) done() }) }) it('should return 10 results, page count = 10 and total count = 100 when limit = 10 and page = 1 sort order = total desc', function (done) { // var sortQuery = TestModel.aggregate(query._pipeline) - TestModel.aggregatePaginate(query, { limit: 10, page: 1, sortBy: { 'total': -1, '_id': -1 } }, function (err, result, pageCount, totalCount) { + TestModel.aggregatePaginate(query, { + limit: 10, + page: 1, + sort: {'total': -1, '_id': -1} + }, function (err, result, pages, total) { if (err) return done(err) result.length.should.equal(10) - pageCount.should.equal(10) - totalCount.should.equal(100) + pages.should.equal(10) + total.should.equal(100) result[0]['total'].should.equal(300) done() }) @@ -154,44 +165,44 @@ describe('Mongoose Aggregate Paginate tests', function () { describe('with limit (Promise)', function () { it('should return 20 results, page count = 5 and total count = 100 when limit is 20', function (done) { - TestModel.aggregatePaginate(query, { limit: 20 }) + TestModel.aggregatePaginate(query, {limit: 20}) .then(function (value) { - value.data.length.should.equal(20) - value.pageCount.should.equal(5) - value.totalCount.should.equal(100) + value.docs.length.should.equal(20) + value.pages.should.equal(5) + value.total.should.equal(100) done() }) .catch(done) }) it('should return 5 results, page count = 20 and total count = 100 when limit is 5', function (done) { - TestModel.aggregatePaginate(query, { limit: 5 }) + TestModel.aggregatePaginate(query, {limit: 5}) .then(function (value) { - value.data.length.should.equal(5) - value.pageCount.should.equal(20) - value.totalCount.should.equal(100) + value.docs.length.should.equal(5) + value.pages.should.equal(20) + value.total.should.equal(100) done() }) .catch(done) }) it('should return 100 results, page count = 1 and total count = 100 when limit is 200', function (done) { - TestModel.aggregatePaginate(query, { limit: 200 }) + TestModel.aggregatePaginate(query, {limit: 200}) .then(function (value) { - value.data.length.should.equal(100) - value.pageCount.should.equal(1) - value.totalCount.should.equal(100) + value.docs.length.should.equal(100) + value.pages.should.equal(1) + value.total.should.equal(100) done() }) .catch(done) }) it('should return 0 results, page count = 1 and total count = 100 when limit = 200 and page = 2', function (done) { - TestModel.aggregatePaginate(query, { limit: 200, page: 2 }) + TestModel.aggregatePaginate(query, {limit: 200, page: 2}) .then(function (value) { - value.data.length.should.equal(0) - value.pageCount.should.equal(1) - value.totalCount.should.equal(100) + value.docs.length.should.equal(0) + value.pages.should.equal(1) + value.total.should.equal(100) done() }) .catch(done) @@ -199,12 +210,12 @@ describe('Mongoose Aggregate Paginate tests', function () { it('should return 10 results, page count = 10 and total count = 100 when limit = 10 and page = 1 sort order = total desc', function (done) { // var sortQuery = TestModel.aggregate(query._pipeline) - TestModel.aggregatePaginate(query, { limit: 10, page: 1, sortBy: { 'total': -1, '_id': -1 } }) + TestModel.aggregatePaginate(query, {limit: 10, page: 1, sort: {'total': -1, '_id': -1}}) .then(function (value) { - value.data.length.should.equal(10) - value.pageCount.should.equal(10) - value.totalCount.should.equal(100) - value.data[0]['total'].should.equal(300) + value.docs.length.should.equal(10) + value.pages.should.equal(10) + value.total.should.equal(100) + value.docs[0]['total'].should.equal(300) done() }) .catch(done) @@ -213,48 +224,56 @@ describe('Mongoose Aggregate Paginate tests', function () { describe('with page (callback)', function () { it('should return 10 results, page count = 10 and total count = 100 when page = 1', function (done) { - TestModel.aggregatePaginate(query, { page: 1 }, function (err, result, pageCount, totalCount) { + TestModel.aggregatePaginate(query, {page: 1}, function (err, result, pages, total) { if (err) return done(err) result.length.should.equal(10) - pageCount.should.equal(10) - totalCount.should.equal(100) + pages.should.equal(10) + total.should.equal(100) done() }) }) it('should return 10 results, page count = 10 and total count = 100 when page = 2', function (done) { - TestModel.aggregatePaginate(query, { page: 2 }, function (err, result, pageCount, totalCount) { + TestModel.aggregatePaginate(query, {page: 2}, function (err, result, pages, total) { if (err) return done(err) result.length.should.equal(10) - pageCount.should.equal(10) - totalCount.should.equal(100) + pages.should.equal(10) + total.should.equal(100) done() }) }) it('should return 10 results, page count = 10 and total count = 100 when page = 10', function (done) { - TestModel.aggregatePaginate(query, { page: 10 }, function (err, result, pageCount, totalCount) { + TestModel.aggregatePaginate(query, {page: 10}, function (err, result, pages, total) { if (err) return done(err) result.length.should.equal(10) - pageCount.should.equal(10) - totalCount.should.equal(100) + pages.should.equal(10) + total.should.equal(100) done() }) }) it('should return 20 results, page count = 5 and total count = 100 when page = 5 , limit = 20 sort total desc', function (done) { - TestModel.aggregatePaginate(query, { page: 5, limit: 20, sortBy: { 'total': -1 } }, function (err, result, pageCount, totalCount) { + TestModel.aggregatePaginate(query, { + page: 5, + limit: 20, + sort: {'total': -1} + }, function (err, result, pages, total) { if (err) return done(err) result.length.should.equal(20) - pageCount.should.equal(5) - totalCount.should.equal(100) + pages.should.equal(5) + total.should.equal(100) result[0]['total'].should.not.equal(300) done() }) }) it('should return error', function (done) { - TestModel.aggregatePaginate(query, { page: -5, limit: 20, sortBy: { 'total': -1 } }, function (err, result, pageCount, totalCount) { + TestModel.aggregatePaginate(query, { + page: -5, + limit: 20, + sort: {'total': -1} + }, function (err, result, pages, total) { if (err) { err.should.should.not.equal(null) done() @@ -264,10 +283,14 @@ describe('Mongoose Aggregate Paginate tests', function () { }) it('should return error', function (done) { var q = TestModel.aggregate() - .project({ 'marksheet': 1, 'studentId': 1 }) + .project({'marksheet': 1, 'studentId': 1}) .unwind('marksheet') - .group({ _id: '$studentId', total: { $sum: '$marksheet.marks' } }) - TestModel.aggregatePaginate(q, { page: -5, limit: 20, sortBy: { 'total': -1 } }, function (err, result, pageCount, totalCount) { + .group({_id: '$studentId', total: {$sum: '$marksheet.marks'}}) + TestModel.aggregatePaginate(q, { + page: -5, + limit: 20, + sort: {'total': -1} + }, function (err, result, pages, total) { if (err) { err.should.should.not.equal(null) done() @@ -281,52 +304,52 @@ describe('Mongoose Aggregate Paginate tests', function () { describe('with page (Promise)', function () { it('should return 10 results, page count = 10 and total count = 100 when page = 1', function (done) { - TestModel.aggregatePaginate(query, { page: 1 }) + TestModel.aggregatePaginate(query, {page: 1}) .then(function (value) { - value.data.length.should.equal(10) - value.pageCount.should.equal(10) - value.totalCount.should.equal(100) + value.docs.length.should.equal(10) + value.pages.should.equal(10) + value.total.should.equal(100) done() }) .catch(done) }) it('should return 10 results, page count = 10 and total count = 100 when page = 2', function (done) { - TestModel.aggregatePaginate(query, { page: 2 }) + TestModel.aggregatePaginate(query, {page: 2}) .then(function (value) { - value.data.length.should.equal(10) - value.pageCount.should.equal(10) - value.totalCount.should.equal(100) + value.docs.length.should.equal(10) + value.pages.should.equal(10) + value.total.should.equal(100) done() }) .catch(done) }) it('should return 10 results, page count = 10 and total count = 100 when page = 10', function (done) { - TestModel.aggregatePaginate(query, { page: 10 }) + TestModel.aggregatePaginate(query, {page: 10}) .then(function (value) { - value.data.length.should.equal(10) - value.pageCount.should.equal(10) - value.totalCount.should.equal(100) + value.docs.length.should.equal(10) + value.pages.should.equal(10) + value.total.should.equal(100) done() }) .catch(done) }) it('should return 20 results, page count = 5 and total count = 100 when page = 5 , limit = 20 sort total desc', function (done) { - TestModel.aggregatePaginate(query, { page: 5, limit: 20, sortBy: { 'total': -1 } }) + TestModel.aggregatePaginate(query, {page: 5, limit: 20, sort: {'total': -1}}) .then(function (value) { - value.data.length.should.equal(20) - value.pageCount.should.equal(5) - value.totalCount.should.equal(100) - value.data[0]['total'].should.not.equal(300) + value.docs.length.should.equal(20) + value.pages.should.equal(5) + value.total.should.equal(100) + value.docs[0]['total'].should.not.equal(300) done() }) .catch(done) }) it('should return error', function (done) { - TestModel.aggregatePaginate(query, { page: -5, limit: 20, sortBy: { 'total': -1 } }) + TestModel.aggregatePaginate(query, {page: -5, limit: 20, sort: {'total': -1}}) .then(function (value) { done('no error return') }) @@ -336,10 +359,10 @@ describe('Mongoose Aggregate Paginate tests', function () { }) it('should return error', function (done) { var q = TestModel.aggregate() - .project({ 'marksheet': 1, 'studentId': 1 }) + .project({'marksheet': 1, 'studentId': 1}) .unwind('marksheet') - .group({ _id: '$studentId', total: { $sum: '$marksheet.marks' } }) - TestModel.aggregatePaginate(q, { page: -5, limit: 20, sortBy: { 'total': -1 } }) + .group({_id: '$studentId', total: {$sum: '$marksheet.marks'}}) + TestModel.aggregatePaginate(q, {page: -5, limit: 20, sort: {'total': -1}}) .then(function (value) { done('no error return') })