From 549b48f97342ae72a54a137a53dc0608170fa6bc Mon Sep 17 00:00:00 2001 From: Peter Pisljar Date: Fri, 12 Jan 2018 16:41:18 +0100 Subject: [PATCH] fixing boolean filters (#15927) (#16013) --- .../__tests__/buckets/create_filter/terms.js | 19 +++++++++++++++++++ .../buckets/_terms_other_bucket_helper.js | 3 ++- .../courier/data_source/_migrate_filter.js | 8 +++++++- .../data_source/build_query/build_es_query.js | 2 +- .../data_source/build_query/from_filters.js | 10 +++++++--- src/ui/public/filter_manager/lib/phrase.js | 5 +++-- 6 files changed, 39 insertions(+), 8 deletions(-) diff --git a/src/ui/public/agg_types/__tests__/buckets/create_filter/terms.js b/src/ui/public/agg_types/__tests__/buckets/create_filter/terms.js index ffc7b0e26ae89..1998dc0e16f90 100644 --- a/src/ui/public/agg_types/__tests__/buckets/create_filter/terms.js +++ b/src/ui/public/agg_types/__tests__/buckets/create_filter/terms.js @@ -34,5 +34,24 @@ describe('AggConfig Filters', function () { expect(filter.meta).to.have.property('index', indexPattern.id); }); + + it('should set query to true or false for boolean filter', () => { + const vis = new Vis(indexPattern, { + type: 'histogram', + aggs: [ { type: 'terms', schema: 'segment', params: { field: 'ssl' } } ] + }); + const aggConfig = vis.aggs.byTypeName.terms[0]; + const filterFalse = createFilter(aggConfig, 0); + expect(filterFalse).to.have.property('query'); + expect(filterFalse.query).to.have.property('match'); + expect(filterFalse.query.match).to.have.property('ssl'); + expect(filterFalse.query.match.ssl).to.have.property('query', false); + + const filterTrue = createFilter(aggConfig, 1); + expect(filterTrue).to.have.property('query'); + expect(filterTrue.query).to.have.property('match'); + expect(filterTrue.query.match).to.have.property('ssl'); + expect(filterTrue.query.match.ssl).to.have.property('query', true); + }); }); }); diff --git a/src/ui/public/agg_types/buckets/_terms_other_bucket_helper.js b/src/ui/public/agg_types/buckets/_terms_other_bucket_helper.js index 4c0865f05b1ad..eabd46d5674b0 100644 --- a/src/ui/public/agg_types/buckets/_terms_other_bucket_helper.js +++ b/src/ui/public/agg_types/buckets/_terms_other_bucket_helper.js @@ -91,6 +91,7 @@ export const OtherBucketHelperProvider = (Private) => { const bucketAggs = aggConfigs.filter(agg => agg.type.type === 'buckets'); const index = bucketAggs.findIndex(agg => agg.id === aggWithOtherBucket.id); const aggs = aggConfigs.toDsl(); + const indexPattern = aggWithOtherBucket.params.field.indexPattern; // create filters aggregation const filterAgg = new AggConfig(aggConfigs[index].vis, { @@ -136,7 +137,7 @@ export const OtherBucketHelperProvider = (Private) => { }); resultAgg.filters.filters[key] = { - bool: buildQueryFromFilters(filters, _.noop) + bool: buildQueryFromFilters(filters, _.noop, indexPattern) }; }; walkBucketTree(0, response.aggregations, bucketAggs[0].id, [], ''); diff --git a/src/ui/public/courier/data_source/_migrate_filter.js b/src/ui/public/courier/data_source/_migrate_filter.js index 78f998ed83fc3..4915e11426081 100644 --- a/src/ui/public/courier/data_source/_migrate_filter.js +++ b/src/ui/public/courier/data_source/_migrate_filter.js @@ -1,11 +1,17 @@ import _ from 'lodash'; +import { getConvertedValueForField } from 'ui/filter_manager/lib/phrase'; -export function migrateFilter(filter) { +export function migrateFilter(filter, indexPattern) { if (filter.match) { const fieldName = Object.keys(filter.match)[0]; + if (isMatchPhraseFilter(filter, fieldName)) { const params = _.get(filter, ['match', fieldName]); + if (indexPattern) { + const field = indexPattern.fields.find(f => f.name === fieldName); + params.query = getConvertedValueForField(field, params.query); + } return { match_phrase: { [fieldName]: _.omit(params, 'type'), diff --git a/src/ui/public/courier/data_source/build_query/build_es_query.js b/src/ui/public/courier/data_source/build_query/build_es_query.js index aca5470b704c0..1026bed66221d 100644 --- a/src/ui/public/courier/data_source/build_query/build_es_query.js +++ b/src/ui/public/courier/data_source/build_query/build_es_query.js @@ -19,7 +19,7 @@ export function BuildESQueryProvider(Private) { const kueryQuery = buildQueryFromKuery(indexPattern, queriesByLanguage.kuery); const kqlQuery = buildQueryFromKql(indexPattern, queriesByLanguage.kql); const luceneQuery = buildQueryFromLucene(queriesByLanguage.lucene, decorateQuery); - const filterQuery = buildQueryFromFilters(filters, decorateQuery); + const filterQuery = buildQueryFromFilters(filters, decorateQuery, indexPattern); return { bool: { diff --git a/src/ui/public/courier/data_source/build_query/from_filters.js b/src/ui/public/courier/data_source/build_query/from_filters.js index 30352b3994588..7dbc03f3e17e3 100644 --- a/src/ui/public/courier/data_source/build_query/from_filters.js +++ b/src/ui/public/courier/data_source/build_query/from_filters.js @@ -39,7 +39,7 @@ const cleanFilter = function (filter) { return _.omit(filter, ['meta', '$state']); }; -export function buildQueryFromFilters(filters, decorateQuery) { +export function buildQueryFromFilters(filters, decorateQuery, indexPattern) { _.each(filters, function (filter) { if (filter.query) { decorateQuery(filter.query); @@ -51,13 +51,17 @@ export function buildQueryFromFilters(filters, decorateQuery) { .filter(filterNegate(false)) .map(translateToQuery) .map(cleanFilter) - .map(migrateFilter), + .map(filter => { + return migrateFilter(filter, indexPattern); + }), filter: [], should: [], must_not: (filters || []) .filter(filterNegate(true)) .map(translateToQuery) .map(cleanFilter) - .map(migrateFilter) + .map(filter => { + return migrateFilter(filter, indexPattern); + }), }; } diff --git a/src/ui/public/filter_manager/lib/phrase.js b/src/ui/public/filter_manager/lib/phrase.js index 914a51305e461..73de0817ce4e4 100644 --- a/src/ui/public/filter_manager/lib/phrase.js +++ b/src/ui/public/filter_manager/lib/phrase.js @@ -1,5 +1,6 @@ export function buildPhraseFilter(field, value, indexPattern) { const filter = { meta: { index: indexPattern.id } }; + const convertedValue = getConvertedValueForField(field, value); if (field.scripted) { filter.script = getPhraseScript(field, value); @@ -7,7 +8,7 @@ export function buildPhraseFilter(field, value, indexPattern) { } else { filter.query = { match: {} }; filter.query.match[field.name] = { - query: value, + query: convertedValue, type: 'phrase' }; } @@ -32,7 +33,7 @@ export function getPhraseScript(field, value) { // See https://github.com/elastic/elasticsearch/issues/20941 and https://github.com/elastic/kibana/issues/8677 // and https://github.com/elastic/elasticsearch/pull/22201 // for the reason behind this change. Aggs now return boolean buckets with a key of 1 or 0. -function getConvertedValueForField(field, value) { +export function getConvertedValueForField(field, value) { if (typeof value !== 'boolean' && field.type === 'boolean') { if (value !== 1 && value !== 0) { throw new Error('Boolean scripted fields must return true or false');