16

I have a read-only API that I'd like Mongoose to always have lean queries for.

Can I enable this either on a schema or connection level to be true by default?

4
  • Doesn't seem that you can apply it at schema level (mongoosejs.com/docs/guide.html#options), so I doubt that you can do it on connection level either :/ Commented Oct 4, 2013 at 14:39
  • 1
    You might consider just using the mongodb native driver directly -- it's always lean. Commented Oct 4, 2013 at 14:58
  • 1
    @WiredPrairie - need mongoose on this project for other reasons, but thanks. Commented Oct 4, 2013 at 15:18
  • 1
    you can use them in the same project. :) Commented Oct 4, 2013 at 15:33

6 Answers 6

18

The easiest way is to monkey patch mongoose.Query class to add default lean option:

var __setOptions = mongoose.Query.prototype.setOptions;

mongoose.Query.prototype.setOptions = function(options, overwrite) {
  __setOptions.apply(this, arguments);
  if (this.options.lean == null) this.options.lean = true;
  return this;
};

Mongoose creates new instance of mongoose.Query for every query and setOptions call is a part of mongoose.Query construction.

By patching mongoose.Query class you'll be able to turn lean queries on globally. So you won't need to path all mongoose methods (find, findOne, findById, findOneAndUpdate, etc.).

Mongoose uses Query class for inner calls like populate. It passes original Query options to each sub-query, so there should be no problems, but be careful with this solution anyway.

Sign up to request clarification or add additional context in comments.

5 Comments

Much better answer than mine, kudos to you!
this does not work with node 6.7.0 and mongoose 4.5.8. Any idea why?
In mongoose 4.5.8 I had to change "this.options.lean" to "this.mongooseOptions.lean".
Using mongoose 5.4.9, it worked by doing: if (this.mongooseOptions().lean == null) { this.mongooseOptions({ lean: true }); }
How would this work in TS? The query return type will still be Document, so the whole typing will be useless. Is there a way to declare that all query returns LeanDocument?
2

A hack-around could be performed something like this:

Current way of executing the query:

Model.find().lean().exec(function (err, docs) {
    docs[0] instanceof mongoose.Document // false
});

Fiddle with the Model's find method:

var findOriginal = Model.prototype.find;
Model.prototype.find = function() {
    return findOriginal.apply(this, arguments).lean();
}

New way of executing the query:

Model.find().exec(function (err, docs) {
    docs[0] instanceof mongoose.Document // false
});

I have not tested this code, but if you have tried to override library functionality in JavaScript before, you will easily grasp where I'm getting

1 Comment

You will of course have to perform this hack for every Model definition, unless you want to dig deeper into the source code of Mongoose :)
2

I have to use My nestjs Application like this. Its perfectly working for me.

import { Query } from 'mongoose'

Query.prototype.setOptions = function(options: any) {
  __setOptions.apply(this, arguments)
  if (!this.mongooseOptions().lean) this.mongooseOptions().lean = true
  return this
}

2 Comments

I want to point out that there is a critical issue with this code sample. If a user explicitly sets the lean option to false, it will set it to true. This is why it is important to do: if (!this.mongooseOptions().lean == null) as this will only fall through if the provided lean option is null or undefined.
@Krrish Which file did you put these codes
0

Refer to the above comments:

mongoose.Query.prototype.setOptions = function(options, overwrite) {
    options = Object.assign({}, options);
    if (!options.hasOwnProperty('lean')) {
        options.lean = true;
    }
    __setOptions.call(this, options, overwrite);
    return this;
};

1 Comment

As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.
0

If you are worried about the accepted answer by @Leonid Beschastny, the places where you should not use lean, according to Mongoose docs are:

  • When you modify the query result
  • You use custom getters or transforms

Source: https://mongoosejs.com/docs/tutorials/lean.html#when-to-use-lean

Comments

0

The easiest way to add the default lean option for a mongoose model. Just add these three lines.

For Example:

const mongoose = require('mongoose');
const BreakTimeTrackerSchema = new mongoose.Schema({
    user_id: {
        type: Number
    },
    company_id: {
        type: Number
    },
    break_time: {
        type: Number
    }
}, {timestamps: true});

BreakTimeTrackerSchema.set('lean', true);
BreakTimeTrackerSchema.set('toObject', { virtuals: true });
BreakTimeTrackerSchema.set('toJSON', { virtuals: true });
module.exports = mongoose.model("break_time_tracker", BreakTimeTrackerSchema);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.