Skip to content

Commit

Permalink
Changing the behavior of virtual only queries
Browse files Browse the repository at this point in the history
If only virtual fields are present in the `select` statement, no real properties will be retrieved from the database.
  • Loading branch information
makinde committed Sep 24, 2018
1 parent 2d9d270 commit c5a822f
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ Allows you to specify which virtuals fields should be returned in find queries w
### Note
* The plugin has no effect on non-lean queries
* Queries can be set as lean using any style, e.g. `myQuery.lean()`, `myQuery.setOptions({ lean: true })`, `myQuery.lean({virtuals: true})`, etc.
* If only virtual fields are present in the `select` statement, no real properties will be retrieved from the database.
* Specifying a virtual field in the `select` statement will exclude non-specified virtual fields, even if lean is set to `{virtuals: true}` (which would normally trigger all virtuals to be included). `Model.find({}, 'virtual_key').lean()` is the same as `.lean({ virtuals: ['virtual_key']})`.

## Getting Started
Expand Down
9 changes: 9 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,15 @@ module.exports = function selectVirtuals(schema) {
this._mongooseOptions.lean = {};
}
this._mongooseOptions.lean.virtuals = virtualFields;

// At this point there was at least one virtual field mentioned in the selection. If
// there are no more fields left in the selection, it means only virtual fields
// were selected and we shouldn't return any real fields. We need to explcitly set
// only the `_id` field to come back since leaving the selection object blank would
// return all real fields.
if (Object.keys(selection).length === 0) {
selection['_id'] = 1;
}
}

next();
Expand Down
7 changes: 7 additions & 0 deletions tests/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,13 @@ test('Virtual field in select, lean set to `true`', async t => {
t.is(result.virtual_key2, undefined);
});

test('Only a virtual field is in the select', async t=> {
const result = await Model.findOne({}, 'virtual_key1').lean().exec();
t.is(result.real_key, undefined, 'Real fields should be excluded if not specified');
t.is(result.virtual_key1, 'v_val1');
t.is(result.virtual_key2, undefined);
});

test('Query is not lean', async t => {
const result = await Model.findOne({}, 'real_key virtual_key1').exec();
t.is(result.real_key, 'foo', 'Real properties should be returned');
Expand Down

0 comments on commit c5a822f

Please sign in to comment.