@jmaitrehenry/elastic-builder
Version:
A JavaScript implementation of the elasticsearch Query DSL
275 lines (230 loc) • 8.96 kB
JavaScript
'use strict';
var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
var _createClass2 = require('babel-runtime/helpers/createClass');
var _createClass3 = _interopRequireDefault(_createClass2);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var isNil = require('lodash.isnil');
/**
* Class supporting the Elasticsearch scripting API.
*
* [Elasticsearch reference](https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-scripting-using.html)
*
* Note: `inline` script type was deprecated in [elasticsearch v5.0](https://www.elastic.co/guide/en/elasticsearch/reference/5.6/breaking_50_scripting.html).
* `source` should be used instead. And similarly for `stored` scripts, type
* `id` must be used instead. `file` scripts were removed as part of the
* breaking changes in [elasticsearch v6.0](https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_scripting_changes.html#_file_scripts_removed)
*
* @param {string=} type One of `inline`, `stored`, `file`, `source`, `id`.
* @param {string=} source Source of the script.
* This needs to be specified if optional argument `type` is passed.
*
* @example
* const script = esb.script('inline', "doc['my_field'] * multiplier")
* .lang('expression')
* .params({ multiplier: 2 });
*
* // cat "log(_score * 2) + my_modifier" > config/scripts/calculate-score.groovy
* const script = esb.script()
* .lang('groovy')
* .file('calculate-score')
* .params({ my_modifier: 2 });
*/
var Script = function () {
// eslint-disable-next-line require-jsdoc
function Script(type, source) {
(0, _classCallCheck3.default)(this, Script);
this._isTypeSet = false;
this._body = {};
// NOTE: Script syntax changed in elasticsearch 5.6 to use `id`/`source`
// instead of `inline`/`source`/`file`. This needs to be handled
// somehow.
if (!isNil(type) && !isNil(source)) {
var typeLower = type.toLowerCase();
switch (typeLower) {
case 'inline':
this.inline(source);
break;
case 'source':
this.source(source);
break;
case 'stored':
this.stored(source);
break;
case 'id':
this.id(source);
break;
case 'file':
this.file(source);
break;
default:
throw new Error('`type` must be one of `inline`, `stored`, `file`');
}
}
}
/**
* Print warning message to console namespaced by class name.
*
* @param {string} msg
* @private
*/
(0, _createClass3.default)(Script, [{
key: '_warn',
value: function _warn(msg) {
console.warn('[Script] ' + msg);
}
/**
* Print warning messages to not mix `Script` source
*
* @private
*/
}, {
key: '_checkMixedRepr',
value: function _checkMixedRepr() {
if (!this._isTypeSet) return;
this._warn('Script source(`inline`/`source`/`stored`/`id`/`file`) was already specified!');
this._warn('Overwriting.');
delete this._body.inline;
delete this._body.source;
delete this._body.stored;
delete this._body.id;
delete this._body.file;
}
/**
* Sets the type of script to be `inline` and specifies the source of the script.
*
* Note: This type was deprecated in elasticsearch v5.0. Use `source`
* instead if you are using elasticsearch `>= 5.0`.
*
* @param {string} scriptCode
* @returns {Script} returns `this` so that calls can be chained.
*/
}, {
key: 'inline',
value: function inline(scriptCode) {
this._checkMixedRepr();
this._body.inline = scriptCode;
this._isTypeSet = true;
return this;
}
/**
* Sets the type of script to be `source` and specifies the source of the script.
*
* Note: `source` is an alias for the `inline` type which was deprecated
* in elasticsearch v5.0. So this type is supported only in versions
* `>= 5.0`.
*
* @param {string} scriptCode
* @returns {Script} returns `this` so that calls can be chained.
*/
}, {
key: 'source',
value: function source(scriptCode) {
this._checkMixedRepr();
this._body.source = scriptCode;
this._isTypeSet = true;
return this;
}
/**
* Specify the `stored` script by `id` which will be retrieved from cluster state.
*
* Note: This type was deprecated in elasticsearch v5.0. Use `id`
* instead if you are using elasticsearch `>= 5.0`.
*
* @param {string} scriptId The unique identifier for the stored script.
* @returns {Script} returns `this` so that calls can be chained.
*/
}, {
key: 'stored',
value: function stored(scriptId) {
this._checkMixedRepr();
this._body.stored = scriptId;
this._isTypeSet = true;
return this;
}
/**
* Specify the stored script to be used by it's `id` which will be retrieved
* from cluster state.
*
* Note: `id` is an alias for the `stored` type which was deprecated in
* elasticsearch v5.0. So this type is supported only in versions `>= 5.0`.
*
* @param {string} scriptId The unique identifier for the stored script.
* @returns {Script} returns `this` so that calls can be chained.
*/
}, {
key: 'id',
value: function id(scriptId) {
this._checkMixedRepr();
this._body.id = scriptId;
this._isTypeSet = true;
return this;
}
/**
* Specify the `file` script by stored as a file in the scripts folder.
*
* Note: File scripts have been removed in elasticsearch 6.0. Instead, use
* stored scripts.
*
* @param {string} fileName The name of the script stored as a file in the scripts folder.
* For script file `config/scripts/calculate-score.groovy`,
* `fileName` should be `calculate-score`
* @returns {Script} returns `this` so that calls can be chained.
*/
}, {
key: 'file',
value: function file(fileName) {
this._checkMixedRepr();
this._body.file = fileName;
this._isTypeSet = true;
return this;
}
/**
* Specifies the language the script is written in. Defaults to `painless` but
* may be set to any of languages listed in [Scripting](https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-scripting.html).
* The default language may be changed in the `elasticsearch.yml` config file by setting
* `script.default_lang` to the appropriate language.
*
* For a `file` script, it should correspond with the script file suffix.
* `groovy` for `config/scripts/calculate-score.groovy`.
*
* Note: The Groovy, JavaScript, and Python scripting languages were
* deprecated in elasticsearch 5.0 and removed in 6.0. Use painless instead.
*
* @param {string} lang The language for the script.
* @returns {Script} returns `this` so that calls can be chained.
*/
}, {
key: 'lang',
value: function lang(_lang) {
this._body.lang = _lang;
return this;
}
/**
* Specifies any named parameters that are passed into the script as variables.
*
* @param {Object} params Named parameters to be passed to script.
* @returns {Script} returns `this` so that calls can be chained.
*/
}, {
key: 'params',
value: function params(_params) {
this._body.params = _params;
return this;
}
/**
* Override default `toJSON` to return DSL representation for the `script`.
*
* @override
* @returns {Object} returns an Object which maps to the elasticsearch query DSL
*/
}, {
key: 'toJSON',
value: function toJSON() {
// recursiveToJSON doesn't seem to be needed here
return this._body;
}
}]);
return Script;
}();
module.exports = Script;