Don't apply query:queryString:options to query_string filters (#15640)

Lukas and I chatted over Slack and we both agreed it didn't really make sense to apply query:queryString:options to query_string filters. If someone is using the advanced query DSL editor to create a query_string filter they probably want full control over it.

This is a breaking change so it will only go in 7.0. In 6.x users should use one of the workarounds.
This commit is contained in:
Matt Bargar 2018-03-29 13:57:16 -04:00 committed by GitHub
parent 52ff625709
commit 811d21148b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 44 additions and 37 deletions

View file

@ -8,3 +8,5 @@ your application from one version of Kibana to another.
--
include::migration/migrate_6_0.asciidoc[]
include::migration/migrate_7_0.asciidoc[]

View file

@ -19,3 +19,12 @@ Kibana 7.0 will only use the Node.js distribution included in the package.
*Impact:* There is no expected impact unless Kibana is installed in a non-standard way.
[float]
=== Advanced setting query:queryString:options no longer applies to filters
*Details:* In previous versions of Kibana the Advanced Setting `query:queryString:options` was applied to both queries
and custom filters using the `query_string` query. This could cause errors if a custom filter used options that
conflicted with the Advanced Setting. In 7.0 `query:queryString:options` will no longer be applied to filters so that
users can have full control over their custom filters.
*Impact:* You must ensure that any saved searches with a `query_string` filter aren't relying implicitly on
`query:queryString:options`.

View file

@ -137,7 +137,7 @@ export const OtherBucketHelperProvider = (Private) => {
});
resultAgg.filters.filters[key] = {
bool: buildQueryFromFilters(filters, _.noop, indexPattern)
bool: buildQueryFromFilters(filters, indexPattern)
};
};
walkBucketTree(0, response.aggregations, bucketAggs[0].id, [], '');

View file

@ -1,18 +1,10 @@
import { buildQueryFromFilters } from '../from_filters';
import { DecorateQueryProvider } from '../../_decorate_query.js';
import ngMock from 'ng_mock';
import { expectDeepEqual } from '../../../../../../test_utils/expect_deep_equal.js';
let decorateQuery;
describe('build query', function () {
describe('buildQueryFromFilters', function () {
beforeEach(ngMock.module('kibana'));
beforeEach(ngMock.inject(function (Private) {
decorateQuery = Private(DecorateQueryProvider);
}));
it('should return the parameters of an Elasticsearch bool query', function () {
const result = buildQueryFromFilters([]);
@ -29,20 +21,20 @@ describe('build query', function () {
const filters = [
{
match_all: {},
meta: { type: 'match_all' }
meta: { type: 'match_all' },
},
{
exists: { field: 'foo' },
meta: { type: 'exists' }
}
meta: { type: 'exists' },
},
];
const expectedESQueries = [
{ match_all: {} },
{ exists: { field: 'foo' } }
{ exists: { field: 'foo' } },
];
const result = buildQueryFromFilters(filters, decorateQuery);
const result = buildQueryFromFilters(filters);
expectDeepEqual(result.must, expectedESQueries);
});
@ -51,15 +43,13 @@ describe('build query', function () {
const filters = [
{
match_all: {},
meta: { type: 'match_all', negate: true }
meta: { type: 'match_all', negate: true },
},
];
const expectedESQueries = [
{ match_all: {} },
];
const expectedESQueries = [{ match_all: {} }];
const result = buildQueryFromFilters(filters, decorateQuery);
const result = buildQueryFromFilters(filters);
expectDeepEqual(result.must_not, expectedESQueries);
});
@ -68,17 +58,17 @@ describe('build query', function () {
const filters = [
{
query: { exists: { field: 'foo' } },
meta: { type: 'exists' }
}
meta: { type: 'exists' },
},
];
const expectedESQueries = [
{
exists: { field: 'foo' }
}
exists: { field: 'foo' },
},
];
const result = buildQueryFromFilters(filters, decorateQuery);
const result = buildQueryFromFilters(filters);
expectDeepEqual(result.must, expectedESQueries);
});
@ -87,21 +77,33 @@ describe('build query', function () {
const filters = [
{
query: { match: { extension: { query: 'foo', type: 'phrase' } } },
meta: { type: 'phrase' }
}
meta: { type: 'phrase' },
},
];
const expectedESQueries = [
{
match_phrase: { extension: { query: 'foo' } },
}
},
];
const result = buildQueryFromFilters(filters, decorateQuery);
const result = buildQueryFromFilters(filters);
expectDeepEqual(result.must, expectedESQueries);
});
});
it('should not add query:queryString:options to query_string filters', function () {
const filters = [
{
query: { query_string: { query: 'foo' } },
meta: { type: 'query_string' },
},
];
const expectedESQueries = [{ query_string: { query: 'foo' } }];
const result = buildQueryFromFilters(filters);
expectDeepEqual(result.must, expectedESQueries);
});
});
});

View file

@ -18,7 +18,7 @@ export function BuildESQueryProvider(Private, config) {
const kueryQuery = buildQueryFromKuery(indexPattern, queriesByLanguage.kuery, config);
const luceneQuery = buildQueryFromLucene(queriesByLanguage.lucene, decorateQuery);
const filterQuery = buildQueryFromFilters(filters, decorateQuery, indexPattern);
const filterQuery = buildQueryFromFilters(filters, indexPattern);
return {
bool: {

View file

@ -39,13 +39,7 @@ const cleanFilter = function (filter) {
return _.omit(filter, ['meta', '$state']);
};
export function buildQueryFromFilters(filters, decorateQuery, indexPattern) {
_.each(filters, function (filter) {
if (filter.query) {
decorateQuery(filter.query);
}
});
export function buildQueryFromFilters(filters, indexPattern) {
return {
must: (filters || [])
.filter(filterNegate(false))