Fix vega specification parsing (#67963)
* add filter clause to es_query_parser.js * update tests to consider the filter clause * update docs to show the new filter clause Co-authored-by: Oleg Ivasenko <oleg.ivasenko@devolo.de>
This commit is contained in:
parent
6ec3c23077
commit
091cece232
|
@ -172,12 +172,19 @@ except that the time range is shifted back by 10 minutes:
|
||||||
// the auto-generated "MUST-NOT" clause
|
// the auto-generated "MUST-NOT" clause
|
||||||
"%dashboard_context-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
|
The `"%timefilter%"` can also be used to specify a single min or max
|
||||||
value. The date_histogram's `extended_bounds` can be set
|
value. The date_histogram's `extended_bounds` can be set
|
||||||
with two values - min and max. Instead of hardcoding a value, you may
|
with two values - min and max. Instead of hardcoding a value, you may
|
||||||
|
|
|
@ -24,6 +24,7 @@ import { isPlainObject, cloneDeep } from 'lodash';
|
||||||
const TIMEFILTER = '%timefilter%';
|
const TIMEFILTER = '%timefilter%';
|
||||||
const AUTOINTERVAL = '%autointerval%';
|
const AUTOINTERVAL = '%autointerval%';
|
||||||
const MUST_CLAUSE = '%dashboard_context-must_clause%';
|
const MUST_CLAUSE = '%dashboard_context-must_clause%';
|
||||||
|
const FILTER_CLAUSE = '%dashboard_context-filter_clause%';
|
||||||
const MUST_NOT_CLAUSE = '%dashboard_context-must_not_clause%';
|
const MUST_NOT_CLAUSE = '%dashboard_context-must_not_clause%';
|
||||||
|
|
||||||
// These values may appear in the 'url': { ... } object
|
// 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 arrays, replace MUST_CLAUSE and MUST_NOT_CLAUSE string elements
|
||||||
for (let pos = 0; pos < obj.length; ) {
|
for (let pos = 0; pos < obj.length; ) {
|
||||||
const item = obj[pos];
|
const item = obj[pos];
|
||||||
if (isQuery && (item === MUST_CLAUSE || item === MUST_NOT_CLAUSE)) {
|
if (
|
||||||
const ctxTag = item === MUST_CLAUSE ? 'must' : 'must_not';
|
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);
|
const ctx = cloneDeep(this._filters);
|
||||||
if (ctx && ctx.bool && ctx.bool[ctxTag]) {
|
if (ctx && ctx.bool && ctx.bool[ctxTag]) {
|
||||||
if (Array.isArray(ctx.bool[ctxTag])) {
|
if (Array.isArray(ctx.bool[ctxTag])) {
|
||||||
|
|
|
@ -28,8 +28,12 @@ const day = 24 * hour;
|
||||||
|
|
||||||
const rangeStart = 10 * day;
|
const rangeStart = 10 * day;
|
||||||
const rangeEnd = 12 * day;
|
const rangeEnd = 12 * day;
|
||||||
const ctxArr = { bool: { must: [{ match_all: { c: 3 } }], must_not: [{ d: 4 }] } };
|
const ctxArr = {
|
||||||
const ctxObj = { bool: { must: { match_all: { a: 1 } }, must_not: { b: 2 } } };
|
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) {
|
function create(min, max, dashboardCtx) {
|
||||||
const inst = new EsQueryParser(
|
const inst = new EsQueryParser(
|
||||||
|
@ -152,16 +156,34 @@ describe(`EsQueryParser.injectQueryContextVars`, () => {
|
||||||
test(
|
test(
|
||||||
`mixed clause arr`,
|
`mixed clause arr`,
|
||||||
check(
|
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
|
ctxArr
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
test(
|
test(
|
||||||
`mixed clause obj`,
|
`mixed clause obj`,
|
||||||
check(
|
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
|
ctxObj
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
@ -229,6 +251,7 @@ describe(`EsQueryParser.parseEsRequest`, () => {
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
must_not: [{ d: 4 }],
|
must_not: [{ d: 4 }],
|
||||||
|
filter: [{ f: 6 }],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in a new issue