mongoose-lean-virtuals

Usage

const mongooseLeanVirtuals = require('mongoose-lean-virtuals');

// Example schema
const userSchema = new mongoose.Schema({ name: String });

userSchema.virtual('lowercase').get(function() {
  return this.name.toLowerCase();
});

// Now, the `lowercase` property will show up even if you do a lean query
userSchema.plugin(mongooseLeanVirtuals);

// Later

// You **must** pass `virtuals: true` to `lean()`, otherwise `lowercase`
// won't be in `res`
const res = await UserModel.find().lean({ virtuals: true });

examples

It attaches virtuals to result of find, findOne, findById, findByIdAndUpdate, and findOneAndUpdate if lean

const schema = new mongoose.Schema({
  name: String
});

schema.virtual('lowercase').get(function() {
  return this.name.toLowerCase();
});

schema.plugin(mongooseLeanVirtuals);

const Model = mongoose.model('Test', schema);

return Model.create({ name: 'Val' }).
  then(() => Promise.all([
    // You **must** pass `virtuals: true` to `lean()`
    Model.find().lean({ virtuals: true }),
    Model.findOne().lean({ virtuals: true }),
    Model.findOneAndUpdate({}, { name: 'VAL' }).lean({ virtuals: true })
  ])).
  then(results => {
    const findRes = results[0];
    const findOneRes = results[1];
    const findOneAndUpdateRes = results[2];
    assert.equal(findRes[0].lowercase, 'val');
    assert.equal(findOneRes.lowercase, 'val');
    assert.equal(findOneAndUpdateRes.lowercase, 'val');

    // Mongoose has an `id` virtual by default that gets the `_id` as a
    // string.
    assert.equal(findRes[0].id, findRes[0]._id.toString());
    assert.equal(findOneRes.id, findOneRes._id.toString());
    assert.equal(findOneAndUpdateRes.id, findOneAndUpdateRes._id.toString());
  });

It lets you choose which virtuals to apply

If you specify a list of virtuals in lean(), this plugin will only apply those virtuals. This lets you pick which virtuals show up.

const schema = new mongoose.Schema({
  name: String
}, { id: false });

schema.virtual('lowercase').get(function() {
  return this.name.toLowerCase();
});
schema.virtual('uppercase').get(function() {
  return this.name.toUpperCase();
});

schema.plugin(mongooseLeanVirtuals);

const Model = mongoose.model('Test2', schema);

return Model.create({ name: 'Val' }).
  then(() => Model.findOne().lean({ virtuals: ['uppercase'] })).
  then(result => {
    assert.equal(result.uppercase, 'VAL');
    assert.ok(!result.lowercase);
  });

It lets you access a lean subdocument's parent

Accessing the parent document is tricky because lean documents don't have a parent() method or any other Mongoose-specific functionality. To support that use case, this plugin exports a parent() function that lets you get a document's parent.

const childSchema = new mongoose.Schema({ firstName: String });
childSchema.virtual('fullName').get(function() {
  if (this instanceof mongoose.Document) {
    return `${this.firstName} ${this.parent().lastName}`;
  }
  // This `fullName` virtual is in a subdocument, so in order to get the
  // parent's `lastName` you need to use this plugin's `parent()` function.
  return `${this.firstName} ${mongooseLeanVirtuals.parent(this).lastName}`;
});

const parentSchema = new mongoose.Schema({
  firstName: String,
  lastName: String,
  child: childSchema
});

parentSchema.plugin(mongooseLeanVirtuals);

const Parent = mongoose.model('Parent', parentSchema);

const doc = {
  firstName: 'Anakin',
  lastName: 'Skywalker',
  child: { firstName: 'Luke' }
};
return Parent.create(doc).
  then(() => Parent.findOne().lean({ virtuals: true })).
  then(result => {
    assert.equal(result.child.fullName, 'Luke Skywalker');
  });

Changelog

0.8.0 / 2021-04-26

0.7.6 / 2020-12-15

0.7.5 / 2020-11-28

0.7.4 / 2020-11-20

0.7.3 / 2020-11-12

0.7.2 / 2020-10-12

0.7.1 / 2020-10-09

0.7.0 / 2020-10-06

0.6.9 / 2020-08-29

0.6.8 / 2020-06-11

0.6.7 / 2020-06-04

0.6.6 / 2020-06-03

0.6.5 / 2020-06-02

0.6.4 / 2020-06-02

0.6.3 / 2020-05-24

0.6.2 / 2020-04-27

0.6.1 / 2020-03-17

0.6.0 / 2020-03-04

0.5.0 / 2019-10-16

0.4.4 / 2019-09-23

0.4.3 / 2019-06-03

0.4.2 / 2019-05-09

0.4.1 / 2019-05-07

0.4.0 / 2019-04-21

0.3.5 / 2019-03-11

0.3.4 / 2018-11-13

0.3.3 / 2018-11-09

0.3.2 / 2018-10-23

0.3.1 / 2018-10-10

0.3.0 / 2018-01-29