UNPKG

elastic-builder

Version:

A JavaScript implementation of the elasticsearch Query DSL

200 lines (181 loc) 5.79 kB
'use strict'; const isNil = require('lodash.isnil'); const { recursiveToJSON } = require('./util'); /** * Class supporting the Elasticsearch search template API. * * The `/_search/template` endpoint allows to use the mustache language to * pre render search requests, before they are executed and fill existing * templates with template parameters. * * [Elasticsearch reference](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-template.html) * * @param {string=} type One of `inline`, `id`, `file`. `id` is also * aliased as `indexed` * @param {string|Object=} source Source of the search template. * This needs to be specified if optional argument `type` is passed. * * @example * const templ = esb.searchTemplate('inline', { * query: esb.matchQuery('{{my_field}}', '{{my_value}}'), * size: '{{my_size}}' * }).params({ * my_field: 'message', * my_value: 'some message', * my_size: 5 * }); * * @example * const templ = new esb.SearchTemplate( * 'inline', * '{ "query": { "terms": {{#toJson}}statuses{{/toJson}} }}' * ).params({ * statuses: { * status: ['pending', 'published'] * } * }); * * @example * const templ = new esb.SearchTemplate( * 'inline', * '{ "query": { "bool": { "must": {{#toJson}}clauses{{/toJson}} } } }' * ).params({ * clauses: [ * esb.termQuery('user', 'boo'), * esb.termQuery('user', 'bar'), * esb.termQuery('user', 'baz') * ] * }); */ class SearchTemplate { // eslint-disable-next-line require-jsdoc constructor(type, source) { this._isTypeSet = false; this._body = {}; if (!isNil(type) && !isNil(source)) { const typeLower = type.toLowerCase(); if ( typeLower !== 'inline' && typeLower !== 'id' && typeLower !== 'indexed' && // alias for id typeLower !== 'file' ) { throw new Error( '`type` must be one of `inline`, `id`, `indexed`, `file`' ); } this[typeLower](source); } } /** * Print warning message to console namespaced by class name. * * @param {string} msg * @private */ _warn(msg) { console.warn(`[SearchTemplate] ${msg}`); } /** * Print warning messages to not mix `SearchTemplate` source * * @private */ _checkMixedRepr() { if (this._isTypeSet) { this._warn( 'Search template source(`inline`/`id`/`file`) was already specified!' ); this._warn('Overwriting.'); delete this._body.file; delete this._body.id; delete this._body.file; } } /** * Helper method to set the type and source * * @param {string} type * @param {*} source * @returns {SearchTemplate} returns `this` so that calls can be chained. * @private */ _setSource(type, source) { this._checkMixedRepr(); this._body[type] = source; this._isTypeSet = true; return this; } /** * Sets the type of search template to be `inline` and specifies the * template with `query` and other optional fields such as `size`. * * @param {string|Object} templ Either an object or a string. * @returns {SearchTemplate} returns `this` so that calls can be chained. */ inline(templ) { return this._setSource('inline', templ); } /** * Specify the indexed search template by `templateName` which will be * retrieved from cluster state. * * @param {string} templId The unique identifier for the indexed template. * @returns {SearchTemplate} returns `this` so that calls can be chained. */ id(templId) { return this._setSource('id', templId); } /** * Specify the indexed search template by `templateName` which will be * retrieved from cluster state. * * Alias for `SearchTemplate.id` * * @param {string} templId The unique identifier for the indexed template. * @returns {SearchTemplate} returns `this` so that calls can be chained. */ indexed(templId) { return this.id(templId); } /** * Specify the search template by filename stored in the scripts folder, * with `mustache` extension. * * @example * // `templId` - Name of the query template in config/scripts/, i.e., * // storedTemplate.mustache. * const templ = new esb.SearchTemplate('file', 'storedTemplate').params({ * query_string: 'search for these words' * }); * * @param {string} fileName The name of the search template stored as a file * in the scripts folder. * For file `config/scripts/storedTemplate.mustache`, * `fileName` should be `storedTemplate` * @returns {SearchTemplate} returns `this` so that calls can be chained. */ file(fileName) { return this._setSource('file', fileName); } /** * Specifies any named parameters that are used to render the search template. * * @param {Object} params Named parameters to be used for rendering. * @returns {SearchTemplate} returns `this` so that calls can be chained. */ params(params) { this._body.params = params; return this; } /** * Override default `toJSON` to return DSL representation for the Search Template. * * @override * @returns {Object} returns an Object which maps to the elasticsearch query DSL */ toJSON() { return recursiveToJSON(this._body); } } module.exports = SearchTemplate;