Reputation: 34667
Is there a way to populate all fields when running a mongoose query, in case you don't know in advance which fields are the referenced documents? Something like this:
schema = new Schema({ ref: {type:ObjectId, ref:'ref'}});
db = Model('data', schema);
db.find({}).populate('*').
// or
db.find({}).populate({path:'*'}).
//=> {ref: {_id:...,}} // "ref" is populated automatically
Upvotes: 6
Views: 8917
Reputation: 1
In my case, for each Model I also have a Class, and inside that Class I include some methods which returns the relevant information required for each case. This allow me to create custom lists of 'filtered' fields per class, used on query options for: what to return on GET routes, what is allowed to modify on PUT routes, and which fields to populate... etc.
When need to add or remove any 'allowed' field just do it on the class method, not all over the rest of the code.
example:
// all imports done
class Users {
// Query parameters
sortBy() { return 'name'; }
getAllFieldsFilter() { return 'name email membertype created_at updated_at'; }
getAllPopulateIndexed() { return { path: 'membertype', select: 'name canpost' };}
// other methods...
constructor() {}
}
module.exports = {
Users,
};
Later it can be used on the queries, for example:
User.find(queryOptions, Users.getAllFieldsFilter())
.sort(Users.sortBy())
.populate(Users.getAllPopulateIndexed());
Upvotes: 0
Reputation: 349
I think it's better to export a variable somewhere that contains the list of all populated fields like :
export const POPULATED_FIELDS = ['filed1','field2']
then when you want to populate the fields just wrtie
Model.findById('some_id').populate(POPULATED_FIELDS)
Upvotes: 2
Reputation: 34667
I wrote a small plugin. It goes through the schema and looks for fields with a ref
property and adds them as a path which is fed to .populate()
in a pre-find hook. Tested with Mongoose v4
function autoPopulateAllFields(schema) {
var paths = '';
schema.eachPath(function process(pathname, schemaType) {
if (pathname=='_id') return;
if (schemaType.options.ref)
paths += ' ' + pathname;
});
schema.pre('find', handler);
schema.pre('findOne', handler);
function handler(next) {
this.populate(paths);
next();
}
};
module.exports = autoPopulateAllFields;
var articleSchema = new Schema({
text: {type: 'String'},
author: {type: 'ObjectId', ref: 'user'}
});
articleSchema.plugin(autoPopulateAllFields);
var Article = mongoose.model('article', articleSchema);
Article.find({}) => [ {text:..., author: { _id:..., name:... /*auto-populated*/} } ]
Upvotes: 6