Skip to content

Commit

Permalink
Merge pull request #3 from limit-zero/projection
Browse files Browse the repository at this point in the history
Add projection option to mongoose pagination
  • Loading branch information
zarathustra323 authored Jul 6, 2018
2 parents aed3ca5 + 4520344 commit 310663a
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 4 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const { Pagination } = require('@limit0/mongoose-graphql-pagination');
```
Use the class constructor to configure the settings for the paginated query.

#### constructor(Model, { criteria = {}, pagination = {}, sort = {} }, options = {})
#### constructor(Model, { criteria = {}, pagination = {}, sort = {}, projection }, options = {})
`Model`: The Mongoose model instance to query. _Required._

`criteria`: A query criteria object to apply to the paginated query. Can be any MongoDB query. For example: `{ deleted: false }` or `{ age: { $gt: 30 } }`. Optional.
Expand All @@ -25,6 +25,8 @@ Use the class constructor to configure the settings for the paginated query.

`sort`: Specifies the sort options. The `field` property specifies the field to sort by, and the order defines the direction. For example: `{ field: 'name', order: -1 }` would sort the edges by name, descending. By default the edges are sorted by ID, ascending. Optional.

`projection`: Specifies the fields to return from the database. For example: `{ field: 1 }` or `{ field: 0 }` would include or exclude the specified field, respectively. If left `undefined`, or as an empty object, all fields will be returned (which is the default behavior). Optional.

`options`: Specifies additional configuration options, such as default limit, max limit, sort collation, and sort created field.

Complete example:
Expand Down
13 changes: 11 additions & 2 deletions src/pagination.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,15 @@ class Pagination {
* @param {object} params.sort The sort parameters
* @param {string} params.sort.field The sort field name.
* @param {string} params.sort.order The sort order. Either 1/-1 or asc/desc.
* @param {?object} params.projection The field projection (fields to return).
* @param {object} options Additional sort and limit options. See the corresponding classes.
*/
constructor(Model, { criteria = {}, pagination = {}, sort = {} } = {}, options = {}) {
constructor(Model, {
criteria = {},
pagination = {},
sort = {},
projection,
} = {}, options = {}) {
this.promises = {};

// Set the Model to use for querying.
Expand All @@ -36,6 +42,9 @@ class Pagination {
// Set the sort criteria.
const { field, order } = sort;
this.sort = new Sort(field, order, options.sort);

// Set the projection.
this.projection = projection;
}

/**
Expand Down Expand Up @@ -63,7 +72,7 @@ class Pagination {
getEdges() {
const run = async () => {
const criteria = await this.getQueryCriteria();
const docs = await this.Model.find(criteria)
const docs = await this.Model.find(criteria, this.projection)
.sort(this.sort.value)
.limit(this.first.value)
.collation(this.sort.collation)
Expand Down
2 changes: 1 addition & 1 deletion test/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ services:
volumes:
- mongodb:/data/db
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:6.2.4
image: docker.elastic.co/elasticsearch/elasticsearch-oss:6.2.4
environment:
- cluster.name=docker-cluster
- bootstrap.memory_lock=true
Expand Down
25 changes: 25 additions & 0 deletions test/pagination.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,31 @@ describe('pagination', function() {
sinon.assert.calledOnce(Pagination.prototype.getQueryCriteria);
});

it('should apply the projection', async function() {
const pagination = { first: 10 };
const projection = { name: 1 };
const paginated = new Pagination(Model, { pagination, projection });
const r1 = await paginated.getEdges();
r1.forEach((edge, i) => {
const { node } = edge;
expect(node.deleted).to.be.undefined;
expect(node.name).to.equal(data[i].name);
});
});

[{}, undefined].forEach((projection) => {
it(`should return all fields when the projection is '${projection}'`, async function() {
const pagination = { first: 10 };
const paginated = new Pagination(Model, { pagination, projection });
const r1 = await paginated.getEdges();
r1.forEach((edge, i) => {
const { node } = edge;
expect(node.deleted).to.equal(data[i].deleted);
expect(node.name).to.equal(data[i].name);
});
});
});

});

describe('#findCursorModel', function() {
Expand Down

0 comments on commit 310663a

Please sign in to comment.