Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Kuery/KQL: Support not passing an index pattern #28010

Merged
merged 2 commits into from
Jan 7, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions packages/kbn-es-query/src/kuery/ast/ast.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ function fromExpression(expression, parseOptions = {}, parse = parseKuery) {
return parse(expression, parseOptions);
}

// indexPattern isn't required, but if you pass one in, we can be more intelligent
// about how we craft the queries (e.g. scripted fields)
export function toElasticsearchQuery(node, indexPattern) {
if (!node || !node.type || !nodeTypes[node.type]) {
return toElasticsearchQuery(nodeTypes.function.buildNode('and', []));
Expand Down
11 changes: 10 additions & 1 deletion packages/kbn-es-query/src/kuery/functions/__tests__/exists.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,21 @@ describe('kuery functions', function () {
expect(_.isEqual(expected, result)).to.be(true);
});

it('should return an ES exists query without an index pattern', function () {
const expected = {
exists: { field: 'response' }
};

const existsNode = nodeTypes.function.buildNode('exists', 'response');
const result = exists.toElasticsearchQuery(existsNode);
expect(_.isEqual(expected, result)).to.be(true);
});

it('should throw an error for scripted fields', function () {
const existsNode = nodeTypes.function.buildNode('exists', 'script string');
expect(exists.toElasticsearchQuery)
.withArgs(existsNode, indexPattern).to.throwException(/Exists query does not support scripted fields/);
});

});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,14 @@ describe('kuery functions', function () {
expect(result.geo_bounding_box.geo).to.have.property('bottom_right', '50.73, -135.35');
});

it('should return an ES geo_bounding_box query without an index pattern', function () {
const node = nodeTypes.function.buildNode('geoBoundingBox', 'geo', params);
const result = geoBoundingBox.toElasticsearchQuery(node);
expect(result).to.have.property('geo_bounding_box');
expect(result.geo_bounding_box.geo).to.have.property('top_left', '73.12, -174.37');
expect(result.geo_bounding_box.geo).to.have.property('bottom_right', '50.73, -135.35');
});

it('should use the ignore_unmapped parameter', function () {
const node = nodeTypes.function.buildNode('geoBoundingBox', 'geo', params);
const result = geoBoundingBox.toElasticsearchQuery(node, indexPattern);
Expand Down
11 changes: 11 additions & 0 deletions packages/kbn-es-query/src/kuery/functions/__tests__/geo_polygon.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,17 @@ describe('kuery functions', function () {
});
});

it('should return an ES geo_polygon query without an index pattern', function () {
const node = nodeTypes.function.buildNode('geoPolygon', 'geo', points);
const result = geoPolygon.toElasticsearchQuery(node);
expect(result).to.have.property('geo_polygon');
expect(result.geo_polygon.geo).to.have.property('points');

result.geo_polygon.geo.points.forEach((point, index) => {
const expectedLatLon = `${points[index].lat}, ${points[index].lon}`;
expect(point).to.be(expectedLatLon);
});
});

it('should use the ignore_unmapped parameter', function () {
const node = nodeTypes.function.buildNode('geoPolygon', 'geo', points);
Expand Down
15 changes: 15 additions & 0 deletions packages/kbn-es-query/src/kuery/functions/__tests__/is.js
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,21 @@ describe('kuery functions', function () {
expect(result).to.eql(expected);
});

it('should return an ES match query when a concrete fieldName and value are provided without an index pattern', function () {
const expected = {
bool: {
should: [
{ match: { extension: 'jpg' } },
],
minimum_should_match: 1
}
};

const node = nodeTypes.function.buildNode('is', 'extension', 'jpg');
const result = is.toElasticsearchQuery(node);
expect(result).to.eql(expected);
});

it('should support creation of phrase queries', function () {
const expected = {
bool: {
Expand Down
22 changes: 22 additions & 0 deletions packages/kbn-es-query/src/kuery/functions/__tests__/range.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,28 @@ describe('kuery functions', function () {
expect(result).to.eql(expected);
});

it('should return an ES range query without an index pattern', function () {
const expected = {
bool: {
should: [
{
range: {
bytes: {
gt: 1000,
lt: 8000
}
}
}
],
minimum_should_match: 1
}
};

const node = nodeTypes.function.buildNode('range', 'bytes', { gt: 1000, lt: 8000 });
const result = range.toElasticsearchQuery(node);
expect(result).to.eql(expected);
});

it('should support wildcard field names', function () {
const expected = {
bool: {
Expand Down
3 changes: 2 additions & 1 deletion packages/kbn-es-query/src/kuery/functions/exists.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
* under the License.
*/

import { get } from 'lodash';
import * as literal from '../node_types/literal';

export function buildNodeParams(fieldName) {
Expand All @@ -28,7 +29,7 @@ export function buildNodeParams(fieldName) {
export function toElasticsearchQuery(node, indexPattern) {
const { arguments: [ fieldNameArg ] } = node;
const fieldName = literal.toElasticsearchQuery(fieldNameArg);
const field = indexPattern.fields.find(field => field.name === fieldName);
const field = get(indexPattern, 'fields', []).find(field => field.name === fieldName);

if (field && field.scripted) {
throw new Error(`Exists query does not support scripted fields`);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export function buildNodeParams(fieldName, params) {
export function toElasticsearchQuery(node, indexPattern) {
const [ fieldNameArg, ...args ] = node.arguments;
const fieldName = nodeTypes.literal.toElasticsearchQuery(fieldNameArg);
const field = indexPattern.fields.find(field => field.name === fieldName);
const field = _.get(indexPattern, 'fields', []).find(field => field.name === fieldName);
const queryParams = args.reduce((acc, arg) => {
const snakeArgName = _.snakeCase(arg.name);
return {
Expand Down
3 changes: 2 additions & 1 deletion packages/kbn-es-query/src/kuery/functions/geo_polygon.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
* under the License.
*/

import { get } from 'lodash';
import { nodeTypes } from '../node_types';
import * as ast from '../ast';

Expand All @@ -35,7 +36,7 @@ export function buildNodeParams(fieldName, points) {
export function toElasticsearchQuery(node, indexPattern) {
const [ fieldNameArg, ...points ] = node.arguments;
const fieldName = nodeTypes.literal.toElasticsearchQuery(fieldNameArg);
const field = indexPattern.fields.find(field => field.name === fieldName);
const field = get(indexPattern, 'fields', []).find(field => field.name === fieldName);
const queryParams = {
points: points.map(ast.toElasticsearchQuery)
};
Expand Down
8 changes: 6 additions & 2 deletions packages/kbn-es-query/src/kuery/functions/is.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ export function buildNodeParams(fieldName, value, isPhrase = false) {
export function toElasticsearchQuery(node, indexPattern) {
const { arguments: [ fieldNameArg, valueArg, isPhraseArg ] } = node;

const fieldName = ast.toElasticsearchQuery(fieldNameArg);
const value = !_.isUndefined(valueArg) ? ast.toElasticsearchQuery(valueArg) : valueArg;
const type = isPhraseArg.value ? 'phrase' : 'best_fields';

Expand All @@ -65,7 +66,7 @@ export function toElasticsearchQuery(node, indexPattern) {
};
}

const fields = getFields(fieldNameArg, indexPattern);
const fields = indexPattern ? getFields(fieldNameArg, indexPattern) : [];

// If no fields are found in the index pattern we send through the given field name as-is. We do this to preserve
// the behaviour of lucene on dashboards where there are panels based on different index patterns that have different
Expand All @@ -80,7 +81,10 @@ export function toElasticsearchQuery(node, indexPattern) {
}

const isExistsQuery = valueArg.type === 'wildcard' && value === '*';
const isMatchAllQuery = isExistsQuery && fields && fields.length === indexPattern.fields.length;
const isAllFieldsQuery =
(fieldNameArg.type === 'wildcard' && fieldName === '*')
|| (fields && indexPattern && fields.length === indexPattern.fields.length);
const isMatchAllQuery = isExistsQuery && isAllFieldsQuery;

if (isMatchAllQuery) {
return { match_all: {} };
Expand Down
2 changes: 1 addition & 1 deletion packages/kbn-es-query/src/kuery/functions/range.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export function buildNodeParams(fieldName, params) {

export function toElasticsearchQuery(node, indexPattern) {
const [ fieldNameArg, ...args ] = node.arguments;
const fields = getFields(fieldNameArg, indexPattern);
const fields = indexPattern ? getFields(fieldNameArg, indexPattern) : [];
const namedArgs = extractArguments(args);
const queryParams = _.mapValues(namedArgs, ast.toElasticsearchQuery);

Expand Down