From 4fdc1d843db0b9306704a3f19ddba0561402007a Mon Sep 17 00:00:00 2001 From: "makary.hryshkin" Date: Mon, 13 Sep 2021 19:26:22 +0200 Subject: [PATCH 1/2] Renamed package to mongoolastic. Updated postSave to populate index refs. Added deleteIndex function. --- lib/index.js | 172 +++++++++++++++++++++++++++------------------- lib/mapping.js | 80 ++++++++++----------- package-lock.json | 2 +- package.json | 2 +- 4 files changed, 143 insertions(+), 113 deletions(-) diff --git a/lib/index.js b/lib/index.js index 070440e..fe30d27 100644 --- a/lib/index.js +++ b/lib/index.js @@ -1,10 +1,10 @@ -'use strict'; +"use strict"; -const mongoose = require('mongoose'); -const generateMapping = require('./mapping').generate; -const client = require('./client'); -const utils = require('./utils'); -const Bulker = require('./bulker'); +const mongoose = require("mongoose"); +const generateMapping = require("./mapping").generate; +const client = require("./client"); +const utils = require("./utils"); +const Bulker = require("./bulker"); module.exports = function(schema, options, version = 5) { // clone main level of options (does not clone deeper) @@ -13,7 +13,7 @@ module.exports = function(schema, options, version = 5) { const cachedMappings = new Map(); let generateType; - if (typeof options.type === 'function') { + if (typeof options.type === "function") { generateType = options.type; } /** @@ -37,8 +37,8 @@ module.exports = function(schema, options, version = 5) { if (!options.index || !options.type) { throw new Error( options.index - ? 'Missing model name to build ES type' - : 'Missing collection name to build ES index' + ? "Missing model name to build ES type" + : "Missing collection name to build ES index" ); } @@ -68,6 +68,7 @@ module.exports = function(schema, options, version = 5) { schema.statics.esSearch = search; schema.statics.esSynchronize = synchronize; schema.statics.esCount = count; + schema.statics.esDeleteIndex = deleteIndex; schema.methods.esOptions = esOptions; schema.methods.esIndex = indexDoc; @@ -75,11 +76,11 @@ module.exports = function(schema, options, version = 5) { schema.methods.esRemove = removeDoc; if (!options.onlyOnDemandIndexing) { - schema.pre('save', preSave); - schema.post('save', postSave); - schema.post('findOneAndUpdate', postSave); - schema.post('remove', postRemove); - schema.post('findOneAndRemove', postRemove); + schema.pre("save", preSave); + schema.post("save", postSave); + schema.post("findOneAndUpdate", postSave); + schema.post("remove", postRemove); + schema.post("findOneAndRemove", postRemove); } }; @@ -99,6 +100,31 @@ module.exports.v7 = function(schema, options) { return module.exports(schema, options, 7); }; +/** + * Deleting an existing index + * static function + * @param {Function} [callback] + * @returns {Promise|undefined} + */ +function deleteIndex(callback) { + const self = this; + + return utils.run(callback, (resolve, reject) => { + const esOptions = self.esOptions(); + + esOptions.client.indices.delete( + { index: esOptions.index }, + (err, result) => { + if (err) { + reject(err); + } else { + resolve(result); + } + } + ); + }); +} + /** * Wraps the model wrapping function with the version number * @param {String} version @@ -118,7 +144,7 @@ function createMappingWithVersion(version) { * @returns {Promise|undefined} */ function createMapping(settings, callback, version) { - if (typeof settings === 'function') { + if (typeof settings === "function") { callback = settings; settings = null; } @@ -162,7 +188,7 @@ function createMapping(settings, callback, version) { createIndexOpts.body.settings.number_of_shards = settings.number_of_shards || 5; } - return esOptions.client.indices.create(createIndexOpts, err => { + return esOptions.client.indices.create(createIndexOpts, (err) => { if (err) { reject(err); return; @@ -192,7 +218,7 @@ function createMapping(settings, callback, version) { * @returns {Promise|undefined} */ function refresh(options, callback) { - if (typeof options === 'function') { + if (typeof options === "function") { callback = options; options = {}; } @@ -224,7 +250,7 @@ function refresh(options, callback) { * @returns {Promise|undefined} */ function count(query, options, callback) { - if (typeof options === 'function') { + if (typeof options === "function") { callback = options; options = {}; } @@ -241,7 +267,7 @@ function count(query, options, callback) { index: esOptions.index, type: esOptions.type, }; - if (typeof query === 'string') { + if (typeof query === "string") { params.q = query; } else { params.body = query.query ? query : { query }; @@ -265,7 +291,7 @@ function count(query, options, callback) { * @returns {Promise|undefined} */ function search(query, options, callback) { - if (typeof options === 'function') { + if (typeof options === "function") { callback = options; options = {}; } @@ -284,7 +310,7 @@ function search(query, options, callback) { type: esOptions.type, }; - if (typeof query === 'string') { + if (typeof query === "string") { params.q = query; } else { params.body = query.query ? query : { query }; @@ -303,9 +329,9 @@ function search(query, options, callback) { return; } - const isObjectId = utils.getType(self.schema.paths._id) === 'objectid'; + const isObjectId = utils.getType(self.schema.paths._id) === "objectid"; - const ids = result.hits.hits.map(hit => + const ids = result.hits.hits.map((hit) => isObjectId ? mongoose.Types.ObjectId(hit._id) : hit._id ); @@ -332,13 +358,13 @@ function search(query, options, callback) { return reject(err); } const userByIds = {}; - users.forEach(user => { + users.forEach((user) => { userByIds[user._id] = user; }); if (docsOnly) { - result = ids.map(id => userByIds[id]); + result = ids.map((id) => userByIds[id]); } else { - result.hits.hits.forEach(hit => { + result.hits.hits.forEach((hit) => { hit.doc = userByIds[hit._id]; }); } @@ -358,16 +384,16 @@ function search(query, options, callback) { * @returns {Promise|undefined} */ function synchronize(conditions, projection, options, callback) { - if (typeof conditions === 'function') { + if (typeof conditions === "function") { callback = conditions; conditions = {}; projection = null; options = null; - } else if (typeof projection === 'function') { + } else if (typeof projection === "function") { callback = projection; projection = null; options = null; - } else if (typeof options === 'function') { + } else if (typeof options === "function") { callback = options; options = null; } @@ -392,8 +418,8 @@ function synchronize(conditions, projection, options, callback) { let streamClosed = false; function finalize() { - bulker.removeListener('error', onError); - bulker.removeListener('sent', onSent); + bulker.removeListener("error", onError); + bulker.removeListener("sent", onSent); esOptions.client.indices.refresh( { index: esOptions.index }, (err, result) => (err ? reject(err) : resolve(result)) @@ -401,7 +427,7 @@ function synchronize(conditions, projection, options, callback) { } function onError(err) { - model.emit('es-bulk-error', err); + model.emit("es-bulk-error", err); if (streamClosed) { finalize(); } else { @@ -410,7 +436,7 @@ function synchronize(conditions, projection, options, callback) { } function onSent(len) { - model.emit('es-bulk-sent', len); + model.emit("es-bulk-sent", len); if (streamClosed) { finalize(); } else { @@ -418,10 +444,10 @@ function synchronize(conditions, projection, options, callback) { } } - bulker.on('error', onError); - bulker.on('sent', onSent); + bulker.on("error", onError); + bulker.on("sent", onSent); - stream.on('data', doc => { + stream.on("data", (doc) => { stream.pause(); let sending; if (!esOptions.filter || esOptions.filter(doc)) { @@ -435,16 +461,16 @@ function synchronize(conditions, projection, options, callback) { }, utils.serialize(doc, esOptions.mapping) ); - model.emit('es-bulk-data', doc); + model.emit("es-bulk-data", doc); } else { - model.emit('es-bulk-filtered', doc); + model.emit("es-bulk-filtered", doc); } if (!sending) { stream.resume(); } }); - stream.on('end', () => { + stream.on("end", () => { streamClosed = true; if (bulker.filled()) { bulker.flush(); @@ -464,24 +490,24 @@ function synchronize(conditions, projection, options, callback) { */ function indexDoc(update, callback) { const self = this; - if (typeof update === 'function') { + if (typeof update === "function") { callback = update; update = false; } return utils.run(callback, (resolve, reject) => { const esOptions = self.esOptions(); let body = utils.serialize(self, esOptions.mapping); - if (typeof esOptions.transform === 'function') { + if (typeof esOptions.transform === "function") { const transformedBody = esOptions.transform(body); if (transformedBody) { body = transformedBody; } } if (update && update.unset) { - (typeof update.unset === 'string' + (typeof update.unset === "string" ? [update.unset] : update.unset - ).forEach(field => { + ).forEach((field) => { body[field] = null; }); } @@ -500,7 +526,7 @@ function indexDoc(update, callback) { * @private */ function _indexDoc(id, body, esOptions, resolve, reject, update) { - esOptions.client[update ? 'update' : 'index']( + esOptions.client[update ? "update" : "index"]( { index: esOptions.index, type: esOptions.type, @@ -531,17 +557,19 @@ function unsetFields(fields, callback) { const esOptions = self.esOptions(); let body; - if (typeof fields === 'string') { + if (typeof fields === "string") { fields = [fields]; } if (esOptions.script) { body = { - script: fields.map(field => `ctx._source.remove("${field}")`).join(';'), + script: fields + .map((field) => `ctx._source.remove("${field}")`) + .join(";"), }; } else { body = { doc: {} }; - fields.forEach(field => { + fields.forEach((field) => { body.doc[field] = null; }); } @@ -574,7 +602,7 @@ function removeDoc(callback) { type: esOptions.type, id: self._id.toString(), }, - err => { + (err) => { if (err) { reject(err); } else { @@ -605,35 +633,37 @@ function preSave(next) { * internal * @param {Object} doc */ -function postSave(doc) { +async function postSave(doc) { if (doc && doc.esOptions) { const data = doc._mexp || {}; const esOptions = doc.esOptions(); delete doc._mexp; if (!esOptions.filter || esOptions.filter(doc)) { - doc - .esIndex(data.wasNew ? false : { unset: data.unset }) - .then(res => { - if (esOptions.script && data.unset && data.unset.length) { - return doc.esUnset(data.unset); - } - return res; - }) - .then(res => { - doc.emit('es-indexed', undefined, res); - doc.constructor.emit('es-indexed', undefined, res); - }) - .catch(err => { - doc.emit('es-indexed', err); - doc.constructor.emit('es-indexed', err); - }); + if (esOptions.populate) { + await doc.populate(esOptions.populate).execPopulate(); + } + + try { + let res = await doc.esIndex( + data.wasNew ? false : { unset: data.unset } + ); + if (esOptions.script && data.unset && data.unset.length) { + res = await doc.esUnset(data.unset); + } + + doc.emit("es-indexed", undefined, res); + doc.constructor.emit("es-indexed", undefined, res); + } catch (err) { + doc.emit("es-indexed", err); + doc.constructor.emit("es-indexed", err); + } } else { - doc.emit('es-filtered'); - doc.constructor.emit('es-filtered'); + doc.emit("es-filtered"); + doc.constructor.emit("es-filtered"); if (!data.wasNew) { doc.esRemove((err, res) => { - doc.emit('es-removed', err, res); - doc.constructor.emit('es-removed', err, res); + doc.emit("es-removed", err, res); + doc.constructor.emit("es-removed", err, res); }); } } @@ -648,8 +678,8 @@ function postSave(doc) { function postRemove(doc) { if (doc && doc.esOptions) { doc.esRemove((err, res) => { - doc.emit('es-removed', err, res); - doc.constructor.emit('es-removed', err, res); + doc.emit("es-removed", err, res); + doc.constructor.emit("es-removed", err, res); }); } } diff --git a/lib/mapping.js b/lib/mapping.js index bcf5a5f..f92257b 100644 --- a/lib/mapping.js +++ b/lib/mapping.js @@ -1,6 +1,6 @@ -'use strict'; +"use strict"; -const utils = require('./utils'); +const utils = require("./utils"); module.exports = {}; @@ -18,9 +18,9 @@ function generate(schema, version) { const explicit = hasExplicit(schema, typeKey); const defaultTypes = getDefault(version); - Object.keys(schema.paths).forEach(name => { + Object.keys(schema.paths).forEach((name) => { // ignore _id because is used as index - if (name === '_id') { + if (name === "_id") { return; } @@ -31,7 +31,7 @@ function generate(schema, version) { if ( explicit && isEmbedded(type) && - !{}.hasOwnProperty.call(options, 'es_indexed') + !{}.hasOwnProperty.call(options, "es_indexed") ) { options.es_indexed = hasExplicit(path.schema, typeKey); } @@ -41,7 +41,7 @@ function generate(schema, version) { } let current = mapping; - const names = name.split('.'); + const names = name.split("."); // handle plain object if (names.length > 1) { @@ -51,7 +51,7 @@ function generate(schema, version) { current = current[name] = { type }; } else { if (!current[name]) { - current[name] = { type: 'object', properties: {} }; + current[name] = { type: "object", properties: {} }; } current = current[name].properties; } @@ -60,13 +60,13 @@ function generate(schema, version) { current = mapping[name] = { type }; } - if (options.es_type && typeof options.es_type === 'object') { - current.type = 'object'; + if (options.es_type && typeof options.es_type === "object") { + current.type = "object"; current.properties = generateESTypeMapping(options.es_type); } else { - if (!{}.hasOwnProperty.call(options, 'es_value') || !options.es_type) { + if (!{}.hasOwnProperty.call(options, "es_value") || !options.es_type) { if (isEmbedded(type)) { - current.type = 'object'; + current.type = "object"; current.properties = generate(path.schema, version); } if (defaultTypes[type]) { @@ -75,16 +75,16 @@ function generate(schema, version) { } // propagate es_ options from schema to mapping - Object.keys(options).forEach(key => { - if (key !== 'es_indexed' && key.substr(0, 3) === 'es_') { + Object.keys(options).forEach((key) => { + if (key !== "es_indexed" && key.substr(0, 3) === "es_") { current[key.substr(3)] = options[key]; } }); } - if ({}.hasOwnProperty.call(options, 'es_value')) { + if ({}.hasOwnProperty.call(options, "es_value")) { current.value = - typeof options.es_value === 'function' + typeof options.es_value === "function" ? options.es_value : function() { return options.es_value; @@ -92,7 +92,7 @@ function generate(schema, version) { } }); - delete mapping[schema.get('versionKey')]; + delete mapping[schema.get("versionKey")]; if (schema.options && schema.options.es_extend) { Object.assign( @@ -105,17 +105,17 @@ function generate(schema, version) { } function isEmbedded(type) { - return type === 'embedded' || type === 'array'; // || type === 'mixed'; + return type === "embedded" || type === "array"; // || type === 'mixed'; } function getTypeKey(schema) { - return schema.options.typeKey || 'type'; + return schema.options.typeKey || "type"; } function hasExplicit(schema, typeKey) { return schema && schema.paths - ? Object.keys(schema.paths).some(name => { - if (name === '_id') { + ? Object.keys(schema.paths).some((name) => { + if (name === "_id") { return; // eslint-disable-line } const path = schema.paths[name]; @@ -125,7 +125,7 @@ function hasExplicit(schema, typeKey) { return true; } } - return {}.hasOwnProperty.call(getOptions(path, typeKey), 'es_indexed'); + return {}.hasOwnProperty.call(getOptions(path, typeKey), "es_indexed"); }) : false; } @@ -144,27 +144,27 @@ function getOptions(path, typeKey) { function generateESTypeMapping(content, esExtendMode) { const properties = {}; // browse properties - Object.keys(content).forEach(key => { - if (content[key] && typeof content[key] === 'object') { + Object.keys(content).forEach((key) => { + if (content[key] && typeof content[key] === "object") { // only browse well formed object properties[key] = {}; - if (content[key].es_type && typeof content[key].es_type === 'object') { - properties[key].type = 'object'; + if (content[key].es_type && typeof content[key].es_type === "object") { + properties[key].type = "object"; properties[key].properties = generateESTypeMapping( content[key].es_type, esExtendMode ); } else { - Object.keys(content[key]).forEach(subkey => { - const targetSubkey = subkey.replace(/^es_/, ''); // remove plugin prefix + Object.keys(content[key]).forEach((subkey) => { + const targetSubkey = subkey.replace(/^es_/, ""); // remove plugin prefix let value = content[key][subkey]; const original = value; // build a function to be ignored in the mapping sent - if (subkey === 'es_value' && esExtendMode) { + if (subkey === "es_value" && esExtendMode) { value = function(_, context) { // serialised function of es_value handle prototype (value, context) where value is always undefined in options.es_extend feature - return typeof original === 'function' + return typeof original === "function" ? original(context.document) : original; }; @@ -186,25 +186,25 @@ function generateESTypeMapping(content, esExtendMode) { function getDefault(version) { if (version === 2) { return { - objectid: 'string', - number: 'double', - mixed: 'object', + objectid: "string", + number: "double", + mixed: "object", }; } if (version === 5 || version === 6) { return { - objectid: 'keyword', - number: 'double', - mixed: 'object', - string: 'text', + objectid: "keyword", + number: "double", + mixed: "object", + string: "text", }; } if (version === 7) { return { - objectid: 'keyword', - number: 'long', - mixed: 'object', - string: 'text', + objectid: "keyword", + number: "long", + mixed: "object", + string: "text", }; } } diff --git a/package-lock.json b/package-lock.json index 4675e96..dd6e5ec 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,5 +1,5 @@ { - "name": "mongoose-elasticsearch-xp", + "name": "mongoolastic", "version": "0.0.0-semantically-released", "lockfileVersion": 1, "requires": true, diff --git a/package.json b/package.json index 8b6d0a7..5c7f936 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "mongoose-elasticsearch-xp", + "name": "mongoolastic", "version": "0.0.0-semantically-released", "description": "A mongoose plugin that indexes models into Elasticsearch 2 / 5 (an alternative to mongoosastic)", "tags": [ From 944967b0be40534ecae4a3789466aeab1b1c4a46 Mon Sep 17 00:00:00 2001 From: "makary.hryshkin" Date: Mon, 13 Sep 2021 19:27:56 +0200 Subject: [PATCH 2/2] Changed library name --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index dd6e5ec..d2360c3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,5 +1,5 @@ { - "name": "mongoolastic", + "name": "@bowery-valuation/eslint-config-client", "version": "0.0.0-semantically-released", "lockfileVersion": 1, "requires": true, diff --git a/package.json b/package.json index 5c7f936..088c788 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "mongoolastic", + "name": "@bowery-valuation/eslint-config-client", "version": "0.0.0-semantically-released", "description": "A mongoose plugin that indexes models into Elasticsearch 2 / 5 (an alternative to mongoosastic)", "tags": [