diff --git a/README.md b/README.md index 4cae925..6fab4be 100644 --- a/README.md +++ b/README.md @@ -88,6 +88,7 @@ Options are: * `protocol` - the protocol the Elasticsearch server uses. Defaults to http. * `hydrate` - whether or not to replace ES source by mongo document. * `filter` - the function used for filtered indexing. +* `transform` - the function used for transforming a document before indexing it, accepts the document as an argument, expects transformed document to be returned (if returned value is falsy, the original document will be used). * `idsOnly` - whether or not returning only mongo ids in `esSearch`. * `countOnly` - whether or not returning only the count value in `esCount`. * `mappingSettings` - default settings to use with `esCreateMapping`. @@ -99,7 +100,6 @@ Options are: * `bulk.delay` - idle time to wait before calling the `client.bulk` function. Defaults to 1000. * `onlyOnDemandIndexing` - whether or not to demand indexing on CRUD operations. If set to true middleware hooks for save, update, delete do not fire. Defaults to false. - To have a model indexed into Elasticsearch simply add the plugin. ```javascript @@ -378,6 +378,24 @@ MovieSchema.plugin(mexp, { }); ``` +### Transforming a document before indexing + +You can specify a function to transform a document before indexing it in ElasticSearch. + +```javascript +var MovieSchema = new mongoose.Schema({ + title: {type: String}, + genre: {type: String, enum: ['horror', 'action', 'adventure', 'other']} +}); + +MovieSchema.plugin(mexp, { + transform: function (doc) { + delete doc.genre; + return doc; + } +}); +``` + Instances of Movie model having 'action' as their genre will be indexed to Elasticsearch. ### Indexing On Demand diff --git a/lib/index.js b/lib/index.js index ebbf713..070440e 100644 --- a/lib/index.js +++ b/lib/index.js @@ -470,7 +470,13 @@ function indexDoc(update, callback) { } return utils.run(callback, (resolve, reject) => { const esOptions = self.esOptions(); - const body = utils.serialize(self, esOptions.mapping); + let body = utils.serialize(self, esOptions.mapping); + if (typeof esOptions.transform === 'function') { + const transformedBody = esOptions.transform(body); + if (transformedBody) { + body = transformedBody; + } + } if (update && update.unset) { (typeof update.unset === 'string' ? [update.unset] diff --git a/test/es7/esIndex.js b/test/es7/esIndex.js index 0032172..516644f 100644 --- a/test/es7/esIndex.js +++ b/test/es7/esIndex.js @@ -17,12 +17,23 @@ describe('esIndex', () => { es_type: 'geo_point', es_boost: 1.5, }, + doNotIndexMe: Boolean, }); - UserSchema.plugin(plugin); + UserSchema.plugin(plugin, { + transform: document => { + delete document.doNotIndexMe; + return document; + }, + }); const UserModel = mongoose.model('User', UserSchema); - const john = new UserModel({ name: 'John', age: 35, pos: [5.7333, 43.5] }); + const john = new UserModel({ + name: 'John', + age: 35, + pos: [5.7333, 43.5], + doNotIndexMe: true, + }); return utils .deleteModelIndexes(UserModel)