Skip to content

Commit

Permalink
feat: updated runtime_mapping work
Browse files Browse the repository at this point in the history
- added jsdocs
  • Loading branch information
atreids committed Feb 28, 2024
1 parent 9f0e0fc commit 3f3f6fc
Show file tree
Hide file tree
Showing 6 changed files with 170 additions and 38 deletions.
4 changes: 3 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
// Place your settings in this file to overwrite default and user settings.
{
"eslint.enable": true,
"eslint.autoFixOnSave": true,
"files.eol": "\n",
"vsicons.presets.angular": false,
"editor.detectIndentation": true,
"[json]": {
"editor.tabSize": 2
},
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit"
}
}
42 changes: 28 additions & 14 deletions src/core/request-body-search.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ const Query = require('./query'),
InnerHits = require('./inner-hits');

const { checkType, setDefault, recursiveToJSON } = require('./util');
const RuntimeField = require('./runtime-field');

/**
* Helper function to call `recursiveToJSON` on elements of array and assign to object.
Expand Down Expand Up @@ -407,12 +408,17 @@ class RequestBodySearch {
}

/**
* Computes a document property dynamically based on the supplied `script`.
* Computes a document property dynamically based on the supplied `runtimeField`.
*
* [Elasticsearch reference](https://www.elastic.co/guide/en/elasticsearch/reference/current/runtime-search-request.html)
*
* Added in Elasticsearch v7.11.0
* [Release note](https://www.elastic.co/guide/en/elasticsearch/reference/7.11/release-notes-7.11.0.html)
*
* @example
* const reqBody = esb.requestBodySearch()
* .query(esb.matchAllQuery())
* .runtimeField(
* .runtimeMapping(
* 'sessionId-name',
* esb.runtimeField(
* 'keyword',
Expand All @@ -424,7 +430,7 @@ class RequestBodySearch {
* // runtime fields can also be used in query aggregation
* const reqBody = esb.requestBodySearch()
* .query(esb.matchAllQuery())
* .runtimeField(
* .runtimeMapping(
* 'sessionId-eventName',
* esb.runtimeField(
* 'keyword',
Expand All @@ -433,41 +439,49 @@ class RequestBodySearch {
* )
* .agg(esb.cardinalityAggregation('uniqueCount', `sessionId-eventName`)),;
*
* @param {string} runtimeFieldName
* @param {RuntimeField} instance of `RuntimeField`
* @param {string} runtimeFieldName Name for the computed runtime mapping field.
* @param {RuntimeField} runtimeField Instance of RuntimeField
*
* @returns {RequestBodySearch} returns `this` so that calls can be chained
*
*/
runtimeMapping(runtimeMappingName, runtimeField) {
runtimeMapping(runtimeFieldName, runtimeField) {
checkType(runtimeField, RuntimeField);

setDefault(this._body, 'runtime_mappings', {});
this._body.runtime_mappings[runtimeMappingName] = runtimeField;
this._body.runtime_mappings[runtimeFieldName] = runtimeField;
return this;
}

/**
* Computes one or more document properties dynamically based on supplied `RuntimeField`s.
*
* [Elasticsearch reference](https://www.elastic.co/guide/en/elasticsearch/reference/current/runtime-search-request.html)
*
* Added in Elasticsearch v7.11.0
* [Release note](https://www.elastic.co/guide/en/elasticsearch/reference/7.11/release-notes-7.11.0.html)
*
* @example
* const fieldA = esb.runtimeField(
* 'keyword',
* `emit(doc['session_id'].value + '::' + doc['name'].value)`,
* 'sessionId-name'
* `emit(doc['session_id'].value + '::' + doc['name'].value)`
* );
* const reqBody = esb.requestBodySearch()
* .query(esb.matchAllQuery())
* .runtimeFields({
* .runtimeMappings({
* 'sessionId-name': fieldA,
* })
*
* @param {Object} runtimeFields Object with `runtimeFieldName` as key and `RuntimeField` instance as the value.
* @param {Object} runtimeMappings Object with `runtimeFieldName` as key and instance of `RuntimeField` as the value.
* @returns {RequestBodySearch} returns `this` so that calls can be chained
*/
runtimeMappings(runtimeMappings) {
checkType(runtimeMappings, Object);

Object.keys(runtimeMappings).forEach(runtimeMappingName =>
Object.keys(runtimeMappings).forEach(runtimeFieldName =>
this.runtimeMapping(
runtimeMappingName,
runtimeMappings[runtimeMappingName]
runtimeFieldName,
runtimeMappings[runtimeFieldName]
)
);

Expand Down
32 changes: 26 additions & 6 deletions src/core/runtime-field.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,24 @@ const validType = [
'lookup'
];

/**
* Class supporting the Elasticsearch runtime field.
*
* [Elasticsearch reference](https://www.elastic.co/guide/en/elasticsearch/reference/current/runtime.html)
*
* Added in Elasticsearch v7.11.0
* [Release note](https://www.elastic.co/guide/en/elasticsearch/reference/7.11/release-notes-7.11.0.html)
*
* @param {string=} type One of `boolean`, `composite`, `date`, `double`, `geo_point`, `ip`, `keyword`, `long`, `lookup`.
* @param {string=} script Source of the script.
*
* @example
* const field = esb.runtimeField('keyword', `emit(doc['sessionId'].value + '::' + doc['name'].value)`);
*/
class RuntimeField {
constructor(type, script, name) {
// eslint-disable-next-line require-jsdoc
constructor(type, script) {
this._body = {};
this._name = name;
this._isTypeSet = false;
this._isScriptSet = false;

Expand All @@ -29,17 +43,23 @@ class RuntimeField {
}
}

name(name) {
this._name = name;
}

/**
* Sets the source of the script.
* @param {string} script
* @returns {void}
*/
script(script) {
this._body.script = {
source: script
};
this._isScriptSet = true;
}

/**
* Sets the type of the runtime field.
* @param {string} type One of `boolean`, `composite`, `date`, `double`, `geo_point`, `ip`, `keyword`, `long`, `lookup`.
* @returns {void}
*/
type(type) {
const typeLower = type.toLowerCase();
if (!validType.includes(typeLower)) {
Expand Down
115 changes: 111 additions & 4 deletions src/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,71 @@ declare namespace esb {
*/
storedFields(fields: object | string): this;

runtimeMapping(runtimeMappingName: string, script: string | RuntimeField): this;


/**
* Computes a document property dynamically based on the supplied `runtimeField`.
*
* [Elasticsearch reference](https://www.elastic.co/guide/en/elasticsearch/reference/current/runtime-search-request.html)
*
* Added in Elasticsearch v7.11.0
* [Release note](https://www.elastic.co/guide/en/elasticsearch/reference/7.11/release-notes-7.11.0.html)
*
* @example
* const reqBody = esb.requestBodySearch()
* .query(esb.matchAllQuery())
* .runtimeMapping(
* 'sessionId-name',
* esb.runtimeField(
* 'keyword',
* `emit(doc['session_id'].value + '::' + doc['name'].value)`
* )
* )
*
* @example
* // runtime fields can also be used in query aggregation
* const reqBody = esb.requestBodySearch()
* .query(esb.matchAllQuery())
* .runtimeMapping(
* 'sessionId-eventName',
* esb.runtimeField(
* 'keyword',
* `emit(doc['session_id'].value + '::' + doc['eventName'].value)`,
* )
* )
* .agg(esb.cardinalityAggregation('uniqueCount', `sessionId-eventName`)),;
*
* @param {string} runtimeFieldName Name for the computed runtime mapping field.
* @param {RuntimeField} runtimeField Instance of RuntimeField
*
* @returns {RequestBodySearch} returns `this` so that calls can be chained
*
*/
runtimeMapping(runtimeFieldName: string, runtimeField: RuntimeField): this;


/**
* Computes one or more document properties dynamically based on supplied `RuntimeField`s.
*
* [Elasticsearch reference](https://www.elastic.co/guide/en/elasticsearch/reference/current/runtime-search-request.html)
*
* Added in Elasticsearch v7.11.0
* [Release note](https://www.elastic.co/guide/en/elasticsearch/reference/7.11/release-notes-7.11.0.html)
*
* @example
* const fieldA = esb.runtimeField(
* 'keyword',
* `emit(doc['session_id'].value + '::' + doc['name'].value)`
* );
* const reqBody = esb.requestBodySearch()
* .query(esb.matchAllQuery())
* .runtimeMappings({
* 'sessionId-name': fieldA,
* })
*
* @param {Object} runtimeMappings Object with `runtimeFieldName` as key and instance of `RuntimeField` as the value.
* @returns {RequestBodySearch} returns `this` so that calls can be chained
*/
runtimeMappings(runtimeMappings: object): this;

/**
Expand Down Expand Up @@ -8764,19 +8828,62 @@ declare namespace esb {
*/
export function highlight(fields?: string | string[]): Highlight;

/**
* Class supporting the Elasticsearch runtime field.
*
* [Elasticsearch reference](https://www.elastic.co/guide/en/elasticsearch/reference/current/runtime.html)
*
* Added in Elasticsearch v7.11.0
* [Release note](https://www.elastic.co/guide/en/elasticsearch/reference/7.11/release-notes-7.11.0.html)
*
* @param {string=} type One of `boolean`, `composite`, `date`, `double`, `geo_point`, `ip`, `keyword`, `long`, `lookup`.
* @param {string=} script Source of the script.
*
* @example
* const field = esb.runtimeField('keyword', `emit(doc['sessionId'].value + '::' + doc['name'].value)`);
*/
export class RuntimeField {
constructor(type?: string, script?: string, name?: string);
name(name: string);
constructor(type?: string, script?: string);

/**
* Sets the type of the runtime field.
*
* @param {string} type One of `boolean`, `composite`, `date`, `double`, `geo_point`, `ip`, `keyword`, `long`, `lookup`.
* @returns {void}
*/
type(type: 'boolean' | 'composite' | 'date' | 'double' | 'geo_point' | 'ip' | 'keyword' | 'long' | 'lookup');

/**
* Sets the source of the script.
*
* @param {string} script
* @returns {void}
*/
script(script: string);

/**
* Override default `toJSON` to return DSL representation for the `script`.
*
* @override
*/
toJSON(): object;
}
export function runtimeField(type?: string, script?: string, name?: string): RuntimeField;

/**
* Class supporting the Elasticsearch runtime field.
*
* [Elasticsearch reference](https://www.elastic.co/guide/en/elasticsearch/reference/current/runtime.html)
*
* Added in Elasticsearch v7.11.0
* [Release note](https://www.elastic.co/guide/en/elasticsearch/reference/7.11/release-notes-7.11.0.html)
*
* @param {string=} type One of `boolean`, `composite`, `date`, `double`, `geo_point`, `ip`, `keyword`, `long`, `lookup`.
* @param {string=} script Source of the script.
*
* @example
* const field = esb.runtimeField('keyword', `emit(doc['sessionId'].value + '::' + doc['name'].value)`);
*/
export function runtimeField(type?: 'boolean' | 'composite' | 'date' | 'double' | 'geo_point' | 'ip' | 'keyword' | 'long' | 'lookup', script?: string): RuntimeField;

/**
* Class supporting the Elasticsearch scripting API.
Expand Down
9 changes: 2 additions & 7 deletions test/core-test/request-body-search.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,10 @@ const suggest = new TermSuggester(
const sortChannel = new Sort('channel', 'desc');
const sortCategories = new Sort('categories', 'desc');

const runtimeFieldA = new RuntimeField(
'keyword',
"emit(doc['name'].value)",
'test1'
);
const runtimeFieldA = new RuntimeField('keyword', "emit(doc['name'].value)");
const runtimeFieldB = new RuntimeField(
'boolean',
"emit(doc['qty'].value > 10)",
'test2'
"emit(doc['qty'].value > 10)"
);

const scriptA = new Script('inline', "doc['my_field_name'].value * 2").lang(
Expand Down
6 changes: 0 additions & 6 deletions test/core-test/runtime-field.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,3 @@ test('type validate and set argument', t => {
'`type` must be one of boolean, composite, date, double, geo_point, ip, keyword, long, lookup'
);
});

test('name set _name', t => {
const fieldA = new RuntimeField();
fieldA.name('field-name');
t.deepEqual(fieldA._name, 'field-name');
});

0 comments on commit 3f3f6fc

Please sign in to comment.