I've added a new property to existing schema with default.
It is important for me to get it on every query.
The problem is while querying old records.
I don't want to miss the "lean" magic but I see that using lean remove virtual fields.
Currently I'm using monkey patching for populating defaults. iterating documents and schema default keys and manually add them to JSON.
Is there a point creating PR with optional query builder something as .find.lean.populateDefaults() or am I breaking the design or creating some other problem?
P.S
migrations are not an option for me.
Thanks
Good point
Excellent point - we also encountered this problem
We are also affected. Please address.
hm this might be difficult, but i'll loop @vkarpov15 in. The whole point of lean queries is to avoid the overhead of a mongoose doc, but it might be possible with a populateDefaults
function to loop over default values and populate them in a lean doc
Great feature request.
Definitely looking forward to the benefit of lean, with defaults. I found a significant slowdown and lean saved me, except I lose all the defaults.
@sonar004 can you share your monkey patch please?
@stephengardner sure:
disclaimer: I'm not sure if this relays on some internal implementation, I think not. Please share if you needed adjustments.
disclaimer2: It is correct to the version of mongoose at the time I've opened the PR.
replace: require('mongoose')
with require the next file:
'use strict';
const mongoose = require('mongoose');
module.exports = ((mongoose) => {
/**
* Add default values of schema when using lean
*
* @param {Function} [model, docs]
* @return {Query} docs
* @api private
*/
function populateDefaults(model, docs) {
var schema = model.base.modelSchemas[model.modelName].obj;
var defaultKeys = Object.keys(schema).filter(function(key) {
return (schema[key] instanceof Object) && schema[key].hasOwnProperty('default');
});
return docs.map(function(doc) {
defaultKeys.forEach(function(key) {
if (!doc.hasOwnProperty(key)) {
doc[key] = schema[key]['default'];
}
});
return doc;
});
}
/**
* Thunk around find()
*
* @param {Function} [callback]
* @return {Query} this
* @api private
*/
mongoose.Query.prototype._find = function(callback) {
if (this._castError) {
callback(this._castError);
return this;
}
this._applyPaths();
this._fields = this._castFields(this._fields);
var fields = this._fieldsForExec();
var options = this._mongooseOptions;
var _this = this;
var cb = function(err, docs) {
if (err) {
return callback(err);
}
if (docs.length === 0) {
return callback(null, docs);
}
if (!options.populate) {
return !!options.lean === true
? callback(null, populateDefaults(_this.model, docs))
: completeMany(_this.model, docs, fields, null, callback);
}
var pop = helpers.preparePopulationOptionsMQ(_this, options);
pop.__noPromise = true;
_this.model.populate(docs, pop, function(err, docs) {
if (err) return callback(err);
return !!options.lean === true
? callback(null, docs)
: completeMany(_this.model, docs, fields, pop, callback);
});
};
return mongoose.Query.base.find.call(this, {}, cb);
};
return mongoose;
})(mongoose);
Hey guys, I've written a package to populate the default values when using lean()
: mongoose-lean-defaults
It's the same idea of mongoose-lean-virtuals.
Please try it out and feel free to open an issue or a PR if something is not working
@DouglasGabr thanks for the plugin :+1: it looks great, I just added a quick PR, and I'll add a note about this to the docs tomorrow
@vkarpov15 I've just released a new version with your changes
Most helpful comment
Hey guys, I've written a package to populate the default values when using
lean()
: mongoose-lean-defaultsIt's the same idea of mongoose-lean-virtuals.
Please try it out and feel free to open an issue or a PR if something is not working