From 773952af032ed841a69cbf51cf5e64697e6dd1f6 Mon Sep 17 00:00:00 2001 From: Oleg Ivasenko Date: Thu, 28 May 2020 15:46:48 +0200 Subject: [PATCH 1/3] add filter clause to es_query_parser.js --- .../public/data_model/es_query_parser.js | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/plugins/vis_type_vega/public/data_model/es_query_parser.js b/src/plugins/vis_type_vega/public/data_model/es_query_parser.js index 387301c2c7de9..f7772ff888a61 100644 --- a/src/plugins/vis_type_vega/public/data_model/es_query_parser.js +++ b/src/plugins/vis_type_vega/public/data_model/es_query_parser.js @@ -24,6 +24,7 @@ import { isPlainObject, cloneDeep } from 'lodash'; const TIMEFILTER = '%timefilter%'; const AUTOINTERVAL = '%autointerval%'; const MUST_CLAUSE = '%dashboard_context-must_clause%'; +const FILTER_CLAUSE = '%dashboard_context-filter_clause%'; const MUST_NOT_CLAUSE = '%dashboard_context-must_not_clause%'; // These values may appear in the 'url': { ... } object @@ -203,8 +204,22 @@ export class EsQueryParser { // For arrays, replace MUST_CLAUSE and MUST_NOT_CLAUSE string elements for (let pos = 0; pos < obj.length; ) { const item = obj[pos]; - if (isQuery && (item === MUST_CLAUSE || item === MUST_NOT_CLAUSE)) { - const ctxTag = item === MUST_CLAUSE ? 'must' : 'must_not'; + if ( + isQuery && + (item === FILTER_CLAUSE || item === MUST_CLAUSE || item === MUST_NOT_CLAUSE) + ) { + let ctxTag = ''; + switch (item) { + case FILTER_CLAUSE: + ctxTag = 'filter'; + break; + case MUST_CLAUSE: + ctxTag = 'must'; + break; + case MUST_NOT_CLAUSE: + ctxTag = 'must_not'; + break; + } const ctx = cloneDeep(this._filters); if (ctx && ctx.bool && ctx.bool[ctxTag]) { if (Array.isArray(ctx.bool[ctxTag])) { From 5d9cc848db83f2e8a2b3f01298add4cf1c10b92c Mon Sep 17 00:00:00 2001 From: Oleg Ivasenko Date: Thu, 28 May 2020 15:59:49 +0200 Subject: [PATCH 2/3] update tests to consider the filter clause --- .../public/data_model/es_query_parser.test.js | 35 +++++++++++++++---- 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/src/plugins/vis_type_vega/public/data_model/es_query_parser.test.js b/src/plugins/vis_type_vega/public/data_model/es_query_parser.test.js index fd474bef73b8c..b04e221fc354e 100644 --- a/src/plugins/vis_type_vega/public/data_model/es_query_parser.test.js +++ b/src/plugins/vis_type_vega/public/data_model/es_query_parser.test.js @@ -28,8 +28,12 @@ const day = 24 * hour; const rangeStart = 10 * day; const rangeEnd = 12 * day; -const ctxArr = { bool: { must: [{ match_all: { c: 3 } }], must_not: [{ d: 4 }] } }; -const ctxObj = { bool: { must: { match_all: { a: 1 } }, must_not: { b: 2 } } }; +const ctxArr = { + bool: { must: [{ match_all: { c: 3 } }], must_not: [{ d: 4 }], filter: [{ f: 6 }] }, +}; +const ctxObj = { + bool: { must: { match_all: { a: 1 } }, must_not: { b: 2 }, filter: { e: 6 } }, +}; function create(min, max, dashboardCtx) { const inst = new EsQueryParser( @@ -152,16 +156,34 @@ describe(`EsQueryParser.injectQueryContextVars`, () => { test( `mixed clause arr`, check( - { arr: [1, '%dashboard_context-must_clause%', 2, '%dashboard_context-must_not_clause%'] }, - { arr: [1, ...ctxArr.bool.must, 2, ...ctxArr.bool.must_not] }, + { + arr: [ + 1, + '%dashboard_context-must_clause%', + 2, + '%dashboard_context-must_not_clause%', + 3, + '%dashboard_context-filter_clause%', + ], + }, + { arr: [1, ...ctxArr.bool.must, 2, ...ctxArr.bool.must_not, 3, ...ctxArr.bool.filter] }, ctxArr ) ); test( `mixed clause obj`, check( - { arr: ['%dashboard_context-must_clause%', 1, '%dashboard_context-must_not_clause%', 2] }, - { arr: [ctxObj.bool.must, 1, ctxObj.bool.must_not, 2] }, + { + arr: [ + '%dashboard_context-must_clause%', + 1, + '%dashboard_context-must_not_clause%', + 2, + '%dashboard_context-filter_clause%', + 3, + ], + }, + { arr: [ctxObj.bool.must, 1, ctxObj.bool.must_not, 2, ctxObj.bool.filter, 3] }, ctxObj ) ); @@ -229,6 +251,7 @@ describe(`EsQueryParser.parseEsRequest`, () => { }, ], must_not: [{ d: 4 }], + filter: [{ f: 6 }], }, }, }, From 9533f87842d5479f2880b09839753dc8333671bc Mon Sep 17 00:00:00 2001 From: Oleg Ivasenko Date: Thu, 28 May 2020 16:00:24 +0200 Subject: [PATCH 3/3] update docs to show the new filter clause --- docs/visualize/vega.asciidoc | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/docs/visualize/vega.asciidoc b/docs/visualize/vega.asciidoc index e0d9955f0c3db..efe9094a14922 100644 --- a/docs/visualize/vega.asciidoc +++ b/docs/visualize/vega.asciidoc @@ -172,12 +172,19 @@ except that the time range is shifted back by 10 minutes: // the auto-generated "MUST-NOT" clause "%dashboard_context-must_not_clause%" ] + filter: [ + // This string will be replaced + // with the auto-generated "FILTER" clause + "%dashboard_context-filter_clause%" + ] } } } } ---- +NOTE: When using `"%context%": true` or defining a value for "%timefield%"` the body cannot contain a query. To customize the query within the VEGA specification (e.g. add an additional filter, or shift the timefilter), define your query and use the placeholders as in the example above. The placeholders will be replaced by the actual context of the dashboard or visualization once parsed. + The `"%timefilter%"` can also be used to specify a single min or max value. The date_histogram's `extended_bounds` can be set with two values - min and max. Instead of hardcoding a value, you may