diff --git a/lib/mongoosastic.js b/lib/mongoosastic.js index a2ebaf9e..7d85f668 100644 --- a/lib/mongoosastic.js +++ b/lib/mongoosastic.js @@ -203,7 +203,9 @@ function Mongoosastic (schema, pluginOpts) { let bulkTimeout let bulkBuffer = [] let esClient + let mongoose = options && options.mongoose let populate = options && options.populate + let populateChildren = options && options.populateChildren let mapping = getMapping(schema) let indexName = options && options.index @@ -239,6 +241,7 @@ function Mongoosastic (schema, pluginOpts) { function postSave (doc) { let _doc + function onIndex (err, res) { if (!filter || !filter(doc)) { doc.emit('es-indexed', err, res) @@ -247,18 +250,44 @@ function Mongoosastic (schema, pluginOpts) { } } + function postPopulate (err, popDoc) { + if (err) { + // console.error('ERROR: Failed to populate children documents. Error:', err); + onIndex(err, popDoc); + } else { + popDoc.index(onIndex); + } + } + + function postPopulateChildren (err, popChildDoc) { + if (err) { + // console.error('ERROR: Failed to populate documents. Error:', err); + postPopulateChildren(err); + } else { + if (populate && populate.length) { + populate.forEach(populateOpts => { + popChildDoc.populate(populateOpts) + }) + popChildDoc.execPopulate().then(popChildDoc => { + postPopulate(null, popChildDoc); + }).catch(postPopulate) + } else { + postPopulate(null, popChildDoc); + } + } + } + if (doc) { _doc = new doc.constructor(doc) - if (populate && populate.length) { - populate.forEach(populateOpts => { - _doc.populate(populateOpts) - }) - _doc.execPopulate().then(popDoc => { - popDoc.index(onIndex) - }).catch(onIndex) + + if (populateChildren && populateChildren.length) { + _doc.populateChildren(populateChildren).then((popChildDoc) => { + postPopulateChildren(null, popChildDoc); + }).catch(postPopulateChildren); } else { - _doc.index(onIndex) + postPopulateChildren(null, _doc); } + } } @@ -343,6 +372,28 @@ function Mongoosastic (schema, pluginOpts) { }, cb) } + schema.methods.populateChildren = function populateChildren (inOpts) { + let promises = [], + opts = inOpts; + opts.forEach(opt => { + promises.push(this.populateChild(opt)); + }); + return Promise.all(promises).then(() => { + return Promise.resolve(this); + }); + }; + + schema.methods.populateChild = function populateChild (inOpts) { + let opts = inOpts, + query = {}; + query[opts.childKey] = { + $in: this.get('_id') + }; + return mongoose.model(opts.ref).find(query).lean().distinct('_id').then(childDocIds => { + this[opts.key] = childDocIds; + }); + }; + /** * @param options Object (optional) * @param cb Function