fixing boolean filters (#15927) (#16013)

This commit is contained in:
Peter Pisljar 2018-01-12 16:41:18 +01:00 committed by GitHub
parent 06b88edede
commit 549b48f973
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 39 additions and 8 deletions

View file

@ -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);
});
});
});

View file

@ -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, [], '');

View file

@ -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'),

View file

@ -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: {

View file

@ -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);
}),
};
}

View file

@ -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');