diff --git a/api_docs/data.json b/api_docs/data.json index b639f5d6d2de7..612b911915f9d 100644 --- a/api_docs/data.json +++ b/api_docs/data.json @@ -11290,7 +11290,7 @@ "description": [], "source": { "path": "src/plugins/data/common/kbn_field_types/types.ts", - "lineNumber": 57 + "lineNumber": 64 }, "initialIsOpen": false }, @@ -20312,7 +20312,7 @@ "description": [], "source": { "path": "src/plugins/data/common/kbn_field_types/types.ts", - "lineNumber": 57 + "lineNumber": 64 }, "initialIsOpen": false }, @@ -26902,7 +26902,7 @@ "description": [], "source": { "path": "src/plugins/data/common/kbn_field_types/types.ts", - "lineNumber": 57 + "lineNumber": 64 }, "initialIsOpen": false } diff --git a/api_docs/data_field_formats.json b/api_docs/data_field_formats.json index fa92d24c03d12..273acdf5fc9ee 100644 --- a/api_docs/data_field_formats.json +++ b/api_docs/data_field_formats.json @@ -3306,7 +3306,7 @@ "description": [], "source": { "path": "src/plugins/data/common/field_formats/converters/string.ts", - "lineNumber": 80 + "lineNumber": 83 }, "signature": [ "({ kind: boolean; text: string; } | { kind: string; text: string; })[]" @@ -3325,7 +3325,7 @@ "returnComment": [], "source": { "path": "src/plugins/data/common/field_formats/converters/string.ts", - "lineNumber": 82 + "lineNumber": 85 } }, { @@ -3342,7 +3342,7 @@ "description": [], "source": { "path": "src/plugins/data/common/field_formats/converters/string.ts", - "lineNumber": 102 + "lineNumber": 105 } } ], @@ -3353,7 +3353,7 @@ "label": "textConvert", "source": { "path": "src/plugins/data/common/field_formats/converters/string.ts", - "lineNumber": 102 + "lineNumber": 105 }, "tags": [], "returnComment": [] diff --git a/api_docs/kibana_react.json b/api_docs/kibana_react.json index 3758b663840d9..7541987ba4215 100644 --- a/api_docs/kibana_react.json +++ b/api_docs/kibana_react.json @@ -887,7 +887,7 @@ "description": [], "source": { "path": "src/plugins/kibana_react/public/field_icon/field_icon.tsx", - "lineNumber": 53 + "lineNumber": 59 } } ], @@ -895,7 +895,7 @@ "returnComment": [], "source": { "path": "src/plugins/kibana_react/public/field_icon/field_icon.tsx", - "lineNumber": 53 + "lineNumber": 59 }, "initialIsOpen": false }, @@ -2066,7 +2066,7 @@ "description": [], "source": { "path": "src/plugins/kibana_react/public/field_icon/field_icon.tsx", - "lineNumber": 27 + "lineNumber": 30 }, "signature": [ "string | undefined" @@ -2080,7 +2080,7 @@ "description": [], "source": { "path": "src/plugins/kibana_react/public/field_icon/field_icon.tsx", - "lineNumber": 28 + "lineNumber": 31 }, "signature": [ "boolean | undefined" @@ -3357,7 +3357,7 @@ "description": [], "source": { "path": "src/plugins/kibana_react/public/field_icon/field_icon.tsx", - "lineNumber": 35 + "lineNumber": 38 } } ], @@ -3365,7 +3365,7 @@ "label": "boolean", "source": { "path": "src/plugins/kibana_react/public/field_icon/field_icon.tsx", - "lineNumber": 35 + "lineNumber": 38 } }, { @@ -3381,7 +3381,7 @@ "description": [], "source": { "path": "src/plugins/kibana_react/public/field_icon/field_icon.tsx", - "lineNumber": 37 + "lineNumber": 40 } }, { @@ -3392,7 +3392,7 @@ "description": [], "source": { "path": "src/plugins/kibana_react/public/field_icon/field_icon.tsx", - "lineNumber": 37 + "lineNumber": 40 } }, { @@ -3403,7 +3403,7 @@ "description": [], "source": { "path": "src/plugins/kibana_react/public/field_icon/field_icon.tsx", - "lineNumber": 37 + "lineNumber": 40 }, "signature": [ "\"square\"" @@ -3416,7 +3416,7 @@ "label": "conflict", "source": { "path": "src/plugins/kibana_react/public/field_icon/field_icon.tsx", - "lineNumber": 37 + "lineNumber": 40 } }, { @@ -3432,7 +3432,7 @@ "description": [], "source": { "path": "src/plugins/kibana_react/public/field_icon/field_icon.tsx", - "lineNumber": 38 + "lineNumber": 41 } } ], @@ -3440,7 +3440,31 @@ "label": "date", "source": { "path": "src/plugins/kibana_react/public/field_icon/field_icon.tsx", - "lineNumber": 38 + "lineNumber": 41 + } + }, + { + "id": "def-public.typeToEuiIconMap.date_range", + "type": "Object", + "tags": [], + "children": [ + { + "tags": [], + "id": "def-public.typeToEuiIconMap.date_range.iconType", + "type": "string", + "label": "iconType", + "description": [], + "source": { + "path": "src/plugins/kibana_react/public/field_icon/field_icon.tsx", + "lineNumber": 42 + } + } + ], + "description": [], + "label": "date_range", + "source": { + "path": "src/plugins/kibana_react/public/field_icon/field_icon.tsx", + "lineNumber": 42 } }, { @@ -3456,7 +3480,7 @@ "description": [], "source": { "path": "src/plugins/kibana_react/public/field_icon/field_icon.tsx", - "lineNumber": 39 + "lineNumber": 43 } } ], @@ -3464,7 +3488,7 @@ "label": "geo_point", "source": { "path": "src/plugins/kibana_react/public/field_icon/field_icon.tsx", - "lineNumber": 39 + "lineNumber": 43 } }, { @@ -3480,7 +3504,7 @@ "description": [], "source": { "path": "src/plugins/kibana_react/public/field_icon/field_icon.tsx", - "lineNumber": 40 + "lineNumber": 44 } } ], @@ -3488,7 +3512,7 @@ "label": "geo_shape", "source": { "path": "src/plugins/kibana_react/public/field_icon/field_icon.tsx", - "lineNumber": 40 + "lineNumber": 44 } }, { @@ -3504,7 +3528,7 @@ "description": [], "source": { "path": "src/plugins/kibana_react/public/field_icon/field_icon.tsx", - "lineNumber": 41 + "lineNumber": 45 } } ], @@ -3512,7 +3536,31 @@ "label": "ip", "source": { "path": "src/plugins/kibana_react/public/field_icon/field_icon.tsx", - "lineNumber": 41 + "lineNumber": 45 + } + }, + { + "id": "def-public.typeToEuiIconMap.ip_range", + "type": "Object", + "tags": [], + "children": [ + { + "tags": [], + "id": "def-public.typeToEuiIconMap.ip_range.iconType", + "type": "string", + "label": "iconType", + "description": [], + "source": { + "path": "src/plugins/kibana_react/public/field_icon/field_icon.tsx", + "lineNumber": 46 + } + } + ], + "description": [], + "label": "ip_range", + "source": { + "path": "src/plugins/kibana_react/public/field_icon/field_icon.tsx", + "lineNumber": 46 } }, { @@ -3528,7 +3576,7 @@ "description": [], "source": { "path": "src/plugins/kibana_react/public/field_icon/field_icon.tsx", - "lineNumber": 43 + "lineNumber": 48 } } ], @@ -3538,7 +3586,7 @@ "label": "murmur3", "source": { "path": "src/plugins/kibana_react/public/field_icon/field_icon.tsx", - "lineNumber": 43 + "lineNumber": 48 } }, { @@ -3554,7 +3602,7 @@ "description": [], "source": { "path": "src/plugins/kibana_react/public/field_icon/field_icon.tsx", - "lineNumber": 44 + "lineNumber": 49 } } ], @@ -3562,7 +3610,31 @@ "label": "number", "source": { "path": "src/plugins/kibana_react/public/field_icon/field_icon.tsx", - "lineNumber": 44 + "lineNumber": 49 + } + }, + { + "id": "def-public.typeToEuiIconMap.number_range", + "type": "Object", + "tags": [], + "children": [ + { + "tags": [], + "id": "def-public.typeToEuiIconMap.number_range.iconType", + "type": "string", + "label": "iconType", + "description": [], + "source": { + "path": "src/plugins/kibana_react/public/field_icon/field_icon.tsx", + "lineNumber": 50 + } + } + ], + "description": [], + "label": "number_range", + "source": { + "path": "src/plugins/kibana_react/public/field_icon/field_icon.tsx", + "lineNumber": 50 } }, { @@ -3578,7 +3650,7 @@ "description": [], "source": { "path": "src/plugins/kibana_react/public/field_icon/field_icon.tsx", - "lineNumber": 45 + "lineNumber": 51 } }, { @@ -3589,7 +3661,7 @@ "description": [], "source": { "path": "src/plugins/kibana_react/public/field_icon/field_icon.tsx", - "lineNumber": 45 + "lineNumber": 51 } } ], @@ -3597,7 +3669,7 @@ "label": "_source", "source": { "path": "src/plugins/kibana_react/public/field_icon/field_icon.tsx", - "lineNumber": 45 + "lineNumber": 51 } }, { @@ -3613,7 +3685,7 @@ "description": [], "source": { "path": "src/plugins/kibana_react/public/field_icon/field_icon.tsx", - "lineNumber": 46 + "lineNumber": 52 } } ], @@ -3621,7 +3693,7 @@ "label": "string", "source": { "path": "src/plugins/kibana_react/public/field_icon/field_icon.tsx", - "lineNumber": 46 + "lineNumber": 52 } }, { @@ -3637,7 +3709,7 @@ "description": [], "source": { "path": "src/plugins/kibana_react/public/field_icon/field_icon.tsx", - "lineNumber": 47 + "lineNumber": 53 } } ], @@ -3645,7 +3717,7 @@ "label": "nested", "source": { "path": "src/plugins/kibana_react/public/field_icon/field_icon.tsx", - "lineNumber": 47 + "lineNumber": 53 } } ], @@ -3653,7 +3725,7 @@ "label": "typeToEuiIconMap", "source": { "path": "src/plugins/kibana_react/public/field_icon/field_icon.tsx", - "lineNumber": 34 + "lineNumber": 37 }, "initialIsOpen": false } diff --git a/api_docs/lens.json b/api_docs/lens.json index 823f9755277f6..7e30ec6a15c3e 100644 --- a/api_docs/lens.json +++ b/api_docs/lens.json @@ -79,7 +79,7 @@ "description": [], "source": { "path": "x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/cardinality.tsx", - "lineNumber": 34 + "lineNumber": 43 }, "signature": [ "\"cardinality\"" @@ -88,7 +88,7 @@ ], "source": { "path": "x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/cardinality.tsx", - "lineNumber": 31 + "lineNumber": 40 }, "initialIsOpen": false }, diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.es_field_types.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.es_field_types.md index ad762cae489c8..30f9189ddb551 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.es_field_types.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.es_field_types.md @@ -25,16 +25,22 @@ export declare enum ES_FIELD_TYPES | BYTE | "byte" | | | DATE | "date" | | | DATE\_NANOS | "date_nanos" | | +| DATE\_RANGE | "date_range" | | | DOUBLE | "double" | | +| DOUBLE\_RANGE | "double_range" | | | FLOAT | "float" | | +| FLOAT\_RANGE | "float_range" | | | GEO\_POINT | "geo_point" | | | GEO\_SHAPE | "geo_shape" | | | HALF\_FLOAT | "half_float" | | | HISTOGRAM | "histogram" | | | INTEGER | "integer" | | +| INTEGER\_RANGE | "integer_range" | | | IP | "ip" | | +| IP\_RANGE | "ip_range" | | | KEYWORD | "keyword" | | | LONG | "long" | | +| LONG\_RANGE | "long_range" | | | MURMUR3 | "murmur3" | | | NESTED | "nested" | | | OBJECT | "object" | | diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.kbn_field_types.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.kbn_field_types.md index 30c3aa946c1ce..4d75dda61d5c9 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.kbn_field_types.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.kbn_field_types.md @@ -21,13 +21,16 @@ export declare enum KBN_FIELD_TYPES | BOOLEAN | "boolean" | | | CONFLICT | "conflict" | | | DATE | "date" | | +| DATE\_RANGE | "date_range" | | | GEO\_POINT | "geo_point" | | | GEO\_SHAPE | "geo_shape" | | | HISTOGRAM | "histogram" | | | IP | "ip" | | +| IP\_RANGE | "ip_range" | | | MURMUR3 | "murmur3" | | | NESTED | "nested" | | | NUMBER | "number" | | +| NUMBER\_RANGE | "number_range" | | | OBJECT | "object" | | | STRING | "string" | | | UNKNOWN | "unknown" | | diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.es_field_types.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.es_field_types.md index 545b7b9d27e10..02199fcc24fe2 100644 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.es_field_types.md +++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.es_field_types.md @@ -25,16 +25,22 @@ export declare enum ES_FIELD_TYPES | BYTE | "byte" | | | DATE | "date" | | | DATE\_NANOS | "date_nanos" | | +| DATE\_RANGE | "date_range" | | | DOUBLE | "double" | | +| DOUBLE\_RANGE | "double_range" | | | FLOAT | "float" | | +| FLOAT\_RANGE | "float_range" | | | GEO\_POINT | "geo_point" | | | GEO\_SHAPE | "geo_shape" | | | HALF\_FLOAT | "half_float" | | | HISTOGRAM | "histogram" | | | INTEGER | "integer" | | +| INTEGER\_RANGE | "integer_range" | | | IP | "ip" | | +| IP\_RANGE | "ip_range" | | | KEYWORD | "keyword" | | | LONG | "long" | | +| LONG\_RANGE | "long_range" | | | MURMUR3 | "murmur3" | | | NESTED | "nested" | | | OBJECT | "object" | | diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.kbn_field_types.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.kbn_field_types.md index a0a64190497c8..be4c3705bd8de 100644 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.kbn_field_types.md +++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.kbn_field_types.md @@ -21,13 +21,16 @@ export declare enum KBN_FIELD_TYPES | BOOLEAN | "boolean" | | | CONFLICT | "conflict" | | | DATE | "date" | | +| DATE\_RANGE | "date_range" | | | GEO\_POINT | "geo_point" | | | GEO\_SHAPE | "geo_shape" | | | HISTOGRAM | "histogram" | | | IP | "ip" | | +| IP\_RANGE | "ip_range" | | | MURMUR3 | "murmur3" | | | NESTED | "nested" | | | NUMBER | "number" | | +| NUMBER\_RANGE | "number_range" | | | OBJECT | "object" | | | STRING | "string" | | | UNKNOWN | "unknown" | | diff --git a/src/plugins/data/common/es_query/filters/build_filters.ts b/src/plugins/data/common/es_query/filters/build_filters.ts index 94388df16dc69..42a4d66359346 100644 --- a/src/plugins/data/common/es_query/filters/build_filters.ts +++ b/src/plugins/data/common/es_query/filters/build_filters.ts @@ -70,6 +70,8 @@ function buildBaseFilter( case 'range': const newParams = { gte: params.from, lt: params.to }; return buildRangeFilter(field, newParams, indexPattern); + case 'range_from_value': + return buildRangeFilter(field, params, indexPattern); case 'exists': return buildExistsFilter(field, indexPattern); default: diff --git a/src/plugins/data/common/es_query/filters/types.ts b/src/plugins/data/common/es_query/filters/types.ts index 557788eea1389..a007189d81a03 100644 --- a/src/plugins/data/common/es_query/filters/types.ts +++ b/src/plugins/data/common/es_query/filters/types.ts @@ -35,6 +35,7 @@ export enum FILTERS { MISSING = 'missing', QUERY_STRING = 'query_string', RANGE = 'range', + RANGE_FROM_VALUE = 'range_from_value', GEO_BOUNDING_BOX = 'geo_bounding_box', GEO_POLYGON = 'geo_polygon', SPATIAL_FILTER = 'spatial_filter', diff --git a/src/plugins/data/common/field_formats/converters/string.ts b/src/plugins/data/common/field_formats/converters/string.ts index 07c6414676551..ec92d75910522 100644 --- a/src/plugins/data/common/field_formats/converters/string.ts +++ b/src/plugins/data/common/field_formats/converters/string.ts @@ -66,9 +66,12 @@ export class StringFormat extends FieldFormat { }); static fieldType = [ KBN_FIELD_TYPES.NUMBER, + KBN_FIELD_TYPES.NUMBER_RANGE, KBN_FIELD_TYPES.BOOLEAN, KBN_FIELD_TYPES.DATE, + KBN_FIELD_TYPES.DATE_RANGE, KBN_FIELD_TYPES.IP, + KBN_FIELD_TYPES.IP_RANGE, KBN_FIELD_TYPES.ATTACHMENT, KBN_FIELD_TYPES.GEO_POINT, KBN_FIELD_TYPES.GEO_SHAPE, diff --git a/src/plugins/data/common/index_patterns/field.stub.ts b/src/plugins/data/common/index_patterns/field.stub.ts index 79f10efe300b5..f76cefe0468bf 100644 --- a/src/plugins/data/common/index_patterns/field.stub.ts +++ b/src/plugins/data/common/index_patterns/field.stub.ts @@ -65,4 +65,12 @@ export const stubFields: IFieldType[] = [ searchable: true, filterable: true, }, + { + name: 'bytes_range', + type: 'number_range', + esTypes: ['integer_range'], + aggregatable: true, + searchable: true, + filterable: true, + }, ]; diff --git a/src/plugins/data/common/kbn_field_types/kbn_field_types.test.ts b/src/plugins/data/common/kbn_field_types/kbn_field_types.test.ts index 8a6663e366852..6209108712c3f 100644 --- a/src/plugins/data/common/kbn_field_types/kbn_field_types.test.ts +++ b/src/plugins/data/common/kbn_field_types/kbn_field_types.test.ts @@ -75,13 +75,16 @@ describe('utils/kbn_field_types', () => { KBN_FIELD_TYPES.BOOLEAN, KBN_FIELD_TYPES.CONFLICT, KBN_FIELD_TYPES.DATE, + KBN_FIELD_TYPES.DATE_RANGE, KBN_FIELD_TYPES.GEO_POINT, KBN_FIELD_TYPES.GEO_SHAPE, KBN_FIELD_TYPES.HISTOGRAM, KBN_FIELD_TYPES.IP, + KBN_FIELD_TYPES.IP_RANGE, KBN_FIELD_TYPES.MURMUR3, KBN_FIELD_TYPES.NESTED, KBN_FIELD_TYPES.NUMBER, + KBN_FIELD_TYPES.NUMBER_RANGE, KBN_FIELD_TYPES.OBJECT, KBN_FIELD_TYPES.STRING, KBN_FIELD_TYPES.UNKNOWN, diff --git a/src/plugins/data/common/kbn_field_types/kbn_field_types_factory.ts b/src/plugins/data/common/kbn_field_types/kbn_field_types_factory.ts index 60b3eb332513a..a48763a5ab788 100644 --- a/src/plugins/data/common/kbn_field_types/kbn_field_types_factory.ts +++ b/src/plugins/data/common/kbn_field_types/kbn_field_types_factory.ts @@ -43,18 +43,41 @@ export const createKbnFieldTypes = (): KbnFieldType[] => [ ES_FIELD_TYPES.TOKEN_COUNT, ], }), + new KbnFieldType({ + name: KBN_FIELD_TYPES.NUMBER_RANGE, + sortable: true, + filterable: true, + esTypes: [ + ES_FIELD_TYPES.FLOAT_RANGE, + ES_FIELD_TYPES.DOUBLE_RANGE, + ES_FIELD_TYPES.INTEGER_RANGE, + ES_FIELD_TYPES.LONG_RANGE, + ], + }), new KbnFieldType({ name: KBN_FIELD_TYPES.DATE, sortable: true, filterable: true, esTypes: [ES_FIELD_TYPES.DATE, ES_FIELD_TYPES.DATE_NANOS], }), + new KbnFieldType({ + name: KBN_FIELD_TYPES.DATE_RANGE, + sortable: true, + filterable: true, + esTypes: [ES_FIELD_TYPES.DATE_RANGE], + }), new KbnFieldType({ name: KBN_FIELD_TYPES.IP, sortable: true, filterable: true, esTypes: [ES_FIELD_TYPES.IP], }), + new KbnFieldType({ + name: KBN_FIELD_TYPES.IP_RANGE, + sortable: true, + filterable: true, + esTypes: [ES_FIELD_TYPES.IP_RANGE], + }), new KbnFieldType({ name: KBN_FIELD_TYPES.BOOLEAN, sortable: true, diff --git a/src/plugins/data/common/kbn_field_types/types.ts b/src/plugins/data/common/kbn_field_types/types.ts index 23cf01c7e406f..c46e5c5266f55 100644 --- a/src/plugins/data/common/kbn_field_types/types.ts +++ b/src/plugins/data/common/kbn_field_types/types.ts @@ -30,6 +30,7 @@ export enum ES_FIELD_TYPES { DATE = 'date', DATE_NANOS = 'date_nanos', + DATE_RANGE = 'date_range', GEO_POINT = 'geo_point', GEO_SHAPE = 'geo_shape', @@ -43,9 +44,15 @@ export enum ES_FIELD_TYPES { SHORT = 'short', UNSIGNED_LONG = 'unsigned_long', + FLOAT_RANGE = 'float_range', + DOUBLE_RANGE = 'double_range', + INTEGER_RANGE = 'integer_range', + LONG_RANGE = 'long_range', + NESTED = 'nested', BYTE = 'byte', IP = 'ip', + IP_RANGE = 'ip_range', ATTACHMENT = 'attachment', TOKEN_COUNT = 'token_count', MURMUR3 = 'murmur3', @@ -59,11 +66,14 @@ export enum KBN_FIELD_TYPES { ATTACHMENT = 'attachment', BOOLEAN = 'boolean', DATE = 'date', + DATE_RANGE = 'date_range', GEO_POINT = 'geo_point', GEO_SHAPE = 'geo_shape', IP = 'ip', + IP_RANGE = 'ip_range', MURMUR3 = 'murmur3', NUMBER = 'number', + NUMBER_RANGE = 'number_range', STRING = 'string', UNKNOWN = 'unknown', CONFLICT = 'conflict', diff --git a/src/plugins/data/common/search/aggs/buckets/date_histogram.ts b/src/plugins/data/common/search/aggs/buckets/date_histogram.ts index 7a91acb7e5a38..61ad66d7efdc9 100644 --- a/src/plugins/data/common/search/aggs/buckets/date_histogram.ts +++ b/src/plugins/data/common/search/aggs/buckets/date_histogram.ts @@ -137,7 +137,7 @@ export const getDateHistogramBucketAgg = ({ { name: 'field', type: 'field', - filterFieldTypes: KBN_FIELD_TYPES.DATE, + filterFieldTypes: [KBN_FIELD_TYPES.DATE, KBN_FIELD_TYPES.DATE_RANGE], default(agg: IBucketDateHistogramAggConfig) { return agg.getIndexPattern().getTimeField?.()?.name; }, diff --git a/src/plugins/data/common/search/aggs/buckets/date_range.ts b/src/plugins/data/common/search/aggs/buckets/date_range.ts index 1014dedb2855e..44b4450650bb4 100644 --- a/src/plugins/data/common/search/aggs/buckets/date_range.ts +++ b/src/plugins/data/common/search/aggs/buckets/date_range.ts @@ -61,7 +61,7 @@ export const getDateRangeBucketAgg = ({ { name: 'field', type: 'field', - filterFieldTypes: KBN_FIELD_TYPES.DATE, + filterFieldTypes: [KBN_FIELD_TYPES.DATE, KBN_FIELD_TYPES.DATE_RANGE], default(agg: IBucketAggConfig) { return agg.getIndexPattern().timeFieldName; }, diff --git a/src/plugins/data/common/search/aggs/buckets/histogram.ts b/src/plugins/data/common/search/aggs/buckets/histogram.ts index e04ebfe494ba9..5d84f132b44d7 100644 --- a/src/plugins/data/common/search/aggs/buckets/histogram.ts +++ b/src/plugins/data/common/search/aggs/buckets/histogram.ts @@ -85,7 +85,7 @@ export const getHistogramBucketAgg = ({ { name: 'field', type: 'field', - filterFieldTypes: KBN_FIELD_TYPES.NUMBER, + filterFieldTypes: [KBN_FIELD_TYPES.NUMBER, KBN_FIELD_TYPES.NUMBER_RANGE], }, { /* @@ -105,6 +105,11 @@ export const getHistogramBucketAgg = ({ options: any ) { const field = aggConfig.getField(); + if (field?.type === 'number_range') { + // Can't scale number_histogram requests + return; + } + const aggBody = field.scripted ? { script: { source: field.script, lang: field.lang } } : { field: field.name }; @@ -163,7 +168,9 @@ export const getHistogramBucketAgg = ({ { name: 'maxBars', shouldShow(agg) { - return isAutoInterval(get(agg, 'params.interval')); + const field = agg.getField(); + // Show this for empty field and number field, but not range + return field?.type !== 'number_range' && isAutoInterval(get(agg, 'params.interval')); }, write: () => {}, }, diff --git a/src/plugins/data/common/search/aggs/buckets/range.ts b/src/plugins/data/common/search/aggs/buckets/range.ts index ed4dbece98f17..8befba60034da 100644 --- a/src/plugins/data/common/search/aggs/buckets/range.ts +++ b/src/plugins/data/common/search/aggs/buckets/range.ts @@ -85,6 +85,7 @@ export const getRangeBucketAgg = ({ getFieldFormatsStart }: RangeBucketAggDepend { name: 'field', type: 'field', + // number_range is not supported by Elasticsearch filterFieldTypes: [KBN_FIELD_TYPES.NUMBER], }, { diff --git a/src/plugins/data/public/public.api.md b/src/plugins/data/public/public.api.md index 9720395881ea3..8c25010f00fd8 100644 --- a/src/plugins/data/public/public.api.md +++ b/src/plugins/data/public/public.api.md @@ -640,10 +640,16 @@ export enum ES_FIELD_TYPES { // (undocumented) DATE_NANOS = "date_nanos", // (undocumented) + DATE_RANGE = "date_range", + // (undocumented) DOUBLE = "double", // (undocumented) + DOUBLE_RANGE = "double_range", + // (undocumented) FLOAT = "float", // (undocumented) + FLOAT_RANGE = "float_range", + // (undocumented) GEO_POINT = "geo_point", // (undocumented) GEO_SHAPE = "geo_shape", @@ -658,12 +664,18 @@ export enum ES_FIELD_TYPES { // (undocumented) INTEGER = "integer", // (undocumented) + INTEGER_RANGE = "integer_range", + // (undocumented) IP = "ip", // (undocumented) + IP_RANGE = "ip_range", + // (undocumented) KEYWORD = "keyword", // (undocumented) LONG = "long", // (undocumented) + LONG_RANGE = "long_range", + // (undocumented) MURMUR3 = "murmur3", // (undocumented) NESTED = "nested", @@ -1745,6 +1757,8 @@ export enum KBN_FIELD_TYPES { // (undocumented) DATE = "date", // (undocumented) + DATE_RANGE = "date_range", + // (undocumented) GEO_POINT = "geo_point", // (undocumented) GEO_SHAPE = "geo_shape", @@ -1753,12 +1767,16 @@ export enum KBN_FIELD_TYPES { // (undocumented) IP = "ip", // (undocumented) + IP_RANGE = "ip_range", + // (undocumented) MURMUR3 = "murmur3", // (undocumented) NESTED = "nested", // (undocumented) NUMBER = "number", // (undocumented) + NUMBER_RANGE = "number_range", + // (undocumented) OBJECT = "object", // (undocumented) _SOURCE = "_source", diff --git a/src/plugins/data/public/query/filter_manager/lib/generate_filter.test.ts b/src/plugins/data/public/query/filter_manager/lib/generate_filter.test.ts index 80477063ba099..1a29a57ff058a 100644 --- a/src/plugins/data/public/query/filter_manager/lib/generate_filter.test.ts +++ b/src/plugins/data/public/query/filter_manager/lib/generate_filter.test.ts @@ -17,6 +17,8 @@ import { buildExistsFilter, PhraseFilter, isPhraseFilter, + RangeFilter, + isRangeFilter, } from '../../../../common'; const INDEX_NAME = 'my-index'; @@ -102,6 +104,53 @@ describe('Generate filters', () => { }); }); + it('should create range filter when provided complex range datatype', () => { + const filters = generateFilters( + mockFilterManager, + { + name: 'my-field', + type: 'ip_range', + } as IFieldType, + { + gt: '192.168.0.0', + lte: '192.168.255.255', + }, + '+', + INDEX_NAME + ); + expect(filters).toHaveLength(1); + expect(filters[0].meta.index === INDEX_NAME); + expect(filters[0].meta.negate).toBeFalsy(); + expect(isRangeFilter(filters[0])).toBeTruthy(); + expect((filters[0] as RangeFilter).range).toEqual({ + [FIELD.name]: { + gt: '192.168.0.0', + lte: '192.168.255.255', + }, + }); + }); + + it('should create a phrase filter on a simple range datatype', () => { + const filters = generateFilters( + mockFilterManager, + { + name: 'my-field', + type: 'number_range', + } as IFieldType, + 10000, + '+', + INDEX_NAME + ); + + expect(filters).toHaveLength(1); + expect(filters[0].meta.index === INDEX_NAME); + expect(filters[0].meta.negate).toBeFalsy(); + expect(isPhraseFilter(filters[0])).toBeTruthy(); + expect((filters[0] as PhraseFilter).query.match_phrase).toEqual({ + [FIELD.name]: 10000, + }); + }); + it('should create multiple phrase filters', () => { const ANOTHER_PHRASE = 'another-value'; const filters = generateFilters( diff --git a/src/plugins/data/public/query/filter_manager/lib/generate_filters.ts b/src/plugins/data/public/query/filter_manager/lib/generate_filters.ts index 86605be7f7644..9a52a02edcd4e 100644 --- a/src/plugins/data/public/query/filter_manager/lib/generate_filters.ts +++ b/src/plugins/data/public/query/filter_manager/lib/generate_filters.ts @@ -90,6 +90,21 @@ export function generateFilters( if (existing) { updateExistingFilter(existing, negate); filter = existing; + } else if (fieldObj.type?.includes('range') && value && typeof value === 'object') { + // When dealing with range fields, the filter type depends on the data passed in. If it's an + // object we assume that it's a min/max value + const tmpIndexPattern = { id: index } as IIndexPattern; + + filter = buildFilter( + tmpIndexPattern, + fieldObj, + FILTERS.RANGE_FROM_VALUE, + false, + false, + value, + null, + FilterStateStore.APP_STATE + ); } else { const tmpIndexPattern = { id: index } as IIndexPattern; // exists filter special case: fieldname = '_exists' and value = fieldname diff --git a/src/plugins/data/public/ui/filter_bar/filter_editor/lib/filter_editor_utils.test.ts b/src/plugins/data/public/ui/filter_bar/filter_editor/lib/filter_editor_utils.test.ts index 484525d878174..32e82df91086b 100644 --- a/src/plugins/data/public/ui/filter_bar/filter_editor/lib/filter_editor_utils.test.ts +++ b/src/plugins/data/public/ui/filter_bar/filter_editor/lib/filter_editor_utils.test.ts @@ -123,6 +123,13 @@ describe('Filter editor utils', () => { const rangeOperator = operatorOptions.find((operator) => operator.type === 'range'); expect(rangeOperator).toBeUndefined(); }); + + it('does not return phrase for number_range fields', () => { + const [field] = stubFields.filter(({ type }) => type === 'string'); + const operatorOptions = getOperatorOptions(field); + const rangeOperator = operatorOptions.find((operator) => operator.type === 'range'); + expect(rangeOperator).toBeUndefined(); + }); }); describe('isFilterValid', () => { diff --git a/src/plugins/data/public/ui/filter_bar/filter_editor/lib/filter_operators.ts b/src/plugins/data/public/ui/filter_bar/filter_editor/lib/filter_operators.ts index 72b69a4f68a10..218f8f5790e44 100644 --- a/src/plugins/data/public/ui/filter_bar/filter_editor/lib/filter_operators.ts +++ b/src/plugins/data/public/ui/filter_bar/filter_editor/lib/filter_operators.ts @@ -56,7 +56,7 @@ export const isBetweenOperator = { }), type: FILTERS.RANGE, negate: false, - fieldTypes: ['number', 'date', 'ip'], + fieldTypes: ['number', 'number_range', 'date', 'date_range', 'ip', 'ip_range'], }; export const isNotBetweenOperator = { @@ -65,7 +65,7 @@ export const isNotBetweenOperator = { }), type: FILTERS.RANGE, negate: true, - fieldTypes: ['number', 'date', 'ip'], + fieldTypes: ['number', 'number_range', 'date', 'date_range', 'ip', 'ip_range'], }; export const existsOperator = { diff --git a/src/plugins/data/public/ui/filter_bar/filter_editor/value_input_type.tsx b/src/plugins/data/public/ui/filter_bar/filter_editor/value_input_type.tsx index ffeef853a15fd..84d53f8cba106 100644 --- a/src/plugins/data/public/ui/filter_bar/filter_editor/value_input_type.tsx +++ b/src/plugins/data/public/ui/filter_bar/filter_editor/value_input_type.tsx @@ -42,6 +42,7 @@ class ValueInputTypeUI extends Component { ); break; case 'number': + case 'number_range': inputElement = ( { ); break; case 'date': + case 'date_range': inputElement = ( { ); break; case 'ip': + case 'ip_range': inputElement = ( `; +exports[`FieldIcon renders known field types date_range is rendered 1`] = ` + +`; + exports[`FieldIcon renders known field types geo_point is rendered 1`] = ` `; +exports[`FieldIcon renders known field types ip_range is rendered 1`] = ` + +`; + exports[`FieldIcon renders known field types murmur3 is rendered 1`] = ` `; +exports[`FieldIcon renders known field types number_range is rendered 1`] = ` + +`; + exports[`FieldIcon renders known field types string is rendered 1`] = ` { | 'boolean' | 'conflict' | 'date' + | 'date_range' | 'geo_point' | 'geo_shape' | 'ip' + | 'ip_range' | 'murmur3' | 'number' + | 'number_range' | '_source' | 'string' | string @@ -36,12 +39,15 @@ export const typeToEuiIconMap: Partial> = { // icon for an index pattern mapping conflict in discover conflict: { iconType: 'alert', color: 'euiColorVis9', shape: 'square' }, date: { iconType: 'tokenDate' }, + date_range: { iconType: 'tokenDate' }, geo_point: { iconType: 'tokenGeo' }, geo_shape: { iconType: 'tokenGeo' }, ip: { iconType: 'tokenIP' }, + ip_range: { iconType: 'tokenIP' }, // is a plugin's data type https://www.elastic.co/guide/en/elasticsearch/plugins/current/mapper-murmur3-usage.html murmur3: { iconType: 'tokenFile' }, number: { iconType: 'tokenNumber' }, + number_range: { iconType: 'tokenNumber' }, _source: { iconType: 'editorCodeBlock', color: 'gray' }, string: { iconType: 'tokenString' }, nested: { iconType: 'tokenNested' }, diff --git a/src/plugins/vis_default_editor/public/components/controls/number_interval.tsx b/src/plugins/vis_default_editor/public/components/controls/number_interval.tsx index 5d875a80469c4..e999350b8b729 100644 --- a/src/plugins/vis_default_editor/public/components/controls/number_interval.tsx +++ b/src/plugins/vis_default_editor/public/components/controls/number_interval.tsx @@ -73,11 +73,12 @@ function NumberIntervalParamEditor({ setValidity, setValue, }: AggParamEditorProps) { - const isAutoChecked = isAutoInterval(value); + const field = agg.getField(); + const fieldSupportsAuto = !field || field.type === 'number'; + const isAutoChecked = fieldSupportsAuto && isAutoInterval(value); const base: number = get(editorConfig, 'interval.base') as number; const min = base || 0; - const isValid = - value !== '' && value !== undefined && (isAutoInterval(value) || Number(value) >= min); + const isValid = value !== '' && value !== undefined && (isAutoChecked || Number(value) >= min); useEffect(() => { setValidity(isValid); @@ -112,6 +113,7 @@ function NumberIntervalParamEditor({ onChange={onAutoSwitchChange} checked={isAutoChecked} compressed + disabled={!fieldSupportsAuto} data-test-subj={`visEditorIntervalSwitch${agg.id}`} /> diff --git a/src/plugins/vis_type_timeseries/public/application/components/aggs/std_deviation.js b/src/plugins/vis_type_timeseries/public/application/components/aggs/std_deviation.js index 4c57ef64a841d..c28cb294c3308 100644 --- a/src/plugins/vis_type_timeseries/public/application/components/aggs/std_deviation.js +++ b/src/plugins/vis_type_timeseries/public/application/components/aggs/std_deviation.js @@ -27,7 +27,7 @@ import { import { injectI18n, FormattedMessage } from '@kbn/i18n/react'; import { KBN_FIELD_TYPES } from '../../../../../../plugins/data/public'; -const RESTRICT_FIELDS = [KBN_FIELD_TYPES.NUMBER]; +const RESTRICT_FIELDS = KBN_FIELD_TYPES.NUMBER; const StandardDeviationAggUi = (props) => { const { series, panel, fields, intl } = props; diff --git a/test/functional/apps/visualize/_area_chart.ts b/test/functional/apps/visualize/_area_chart.ts index 05fbdc2e0c283..1ae476b0868fb 100644 --- a/test/functional/apps/visualize/_area_chart.ts +++ b/test/functional/apps/visualize/_area_chart.ts @@ -443,7 +443,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { ); const errorMessage = await fieldErrorMessage.getVisibleText(); expect(errorMessage).to.be( - 'The index pattern test_index* does not contain any of the following compatible field types: date' + 'The index pattern test_index* does not contain any of the following compatible field types: date or date_range' ); }); }); diff --git a/test/functional/apps/visualize/_histogram_request_start.ts b/test/functional/apps/visualize/_histogram_request_start.ts index a232d58f8cb18..b027dbcd57780 100644 --- a/test/functional/apps/visualize/_histogram_request_start.ts +++ b/test/functional/apps/visualize/_histogram_request_start.ts @@ -71,5 +71,16 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { }); }); }); + + describe('autoBounds are not set for number_range data', function () { + it('should use provided value when number of generated buckets is less than histogram:maxBars', async function () { + log.debug('Field = machine.ram_range'); + await PageObjects.visEditor.selectField('machine.ram_range'); + await retry.waitFor('interval to be set', async () => { + return Boolean(await PageObjects.visEditor.getNumericInterval()); + }); + expect(await PageObjects.visEditor.getNumericInterval()).to.eql(100); + }); + }); }); } diff --git a/test/functional/fixtures/es_archiver/logstash_functional/data.json.gz b/test/functional/fixtures/es_archiver/logstash_functional/data.json.gz index a4f889da61128..b3a5facb1a948 100644 Binary files a/test/functional/fixtures/es_archiver/logstash_functional/data.json.gz and b/test/functional/fixtures/es_archiver/logstash_functional/data.json.gz differ diff --git a/test/functional/fixtures/es_archiver/logstash_functional/mappings.json b/test/functional/fixtures/es_archiver/logstash_functional/mappings.json index 010abff9cf6a9..7a1fdcba5cf58 100644 --- a/test/functional/fixtures/es_archiver/logstash_functional/mappings.json +++ b/test/functional/fixtures/es_archiver/logstash_functional/mappings.json @@ -127,6 +127,9 @@ }, "ram": { "type": "long" + }, + "ram_range": { + "type": "long_range" } } }, @@ -500,6 +503,9 @@ }, "ram": { "type": "long" + }, + "ram_range": { + "type": "long_range" } } }, @@ -873,6 +879,9 @@ }, "ram": { "type": "long" + }, + "ram_range": { + "type": "long_range" } } }, @@ -1115,4 +1124,4 @@ } } } -} +} \ No newline at end of file diff --git a/x-pack/plugins/data_enhanced/public/autocomplete/providers/kql_query_suggestion/__fixtures__/index_pattern_response.json b/x-pack/plugins/data_enhanced/public/autocomplete/providers/kql_query_suggestion/__fixtures__/index_pattern_response.json index 27e480623f311..b69403326f74c 100644 --- a/x-pack/plugins/data_enhanced/public/autocomplete/providers/kql_query_suggestion/__fixtures__/index_pattern_response.json +++ b/x-pack/plugins/data_enhanced/public/autocomplete/providers/kql_query_suggestion/__fixtures__/index_pattern_response.json @@ -12,6 +12,16 @@ "aggregatable": true, "readFromDocValues": true }, + { + "name": "bytes_range", + "type": "number_range", + "esTypes": ["long_range"], + "count": 10, + "scripted": false, + "searchable": true, + "aggregatable": true, + "readFromDocValues": true + }, { "name": "ssl", "type": "boolean", @@ -42,6 +52,16 @@ "aggregatable": true, "readFromDocValues": true }, + { + "name": "time_range", + "type": "date_range", + "esTypes": ["date_range"], + "count": 10, + "scripted": false, + "searchable": true, + "aggregatable": true, + "readFromDocValues": true + }, { "name": "@tags", "type": "string", @@ -82,6 +102,16 @@ "aggregatable": true, "readFromDocValues": true }, + { + "name": "ip_range", + "type": "ip_range", + "esTypes": ["ip_range"], + "count": 0, + "scripted": false, + "searchable": true, + "aggregatable": true, + "readFromDocValues": true + }, { "name": "request_body", "type": "attachment", diff --git a/x-pack/plugins/data_enhanced/public/autocomplete/providers/kql_query_suggestion/operator.test.ts b/x-pack/plugins/data_enhanced/public/autocomplete/providers/kql_query_suggestion/operator.test.ts index dafc11167e707..bd021b0d0dac5 100644 --- a/x-pack/plugins/data_enhanced/public/autocomplete/providers/kql_query_suggestion/operator.test.ts +++ b/x-pack/plugins/data_enhanced/public/autocomplete/providers/kql_query_suggestion/operator.test.ts @@ -70,6 +70,36 @@ describe('Kuery operator suggestions', () => { expect(suggestions.find(({ text }) => text === '< ')).toBeDefined(); }); + test('should return numeric operators for numeric range fields', async () => { + const suggestions = await getSuggestions( + querySuggestionsArgs, + mockKueryNode({ fieldName: 'bytes_range' }) + ); + + expect(suggestions.find(({ text }) => text === ': ')).toBeDefined(); + expect(suggestions.find(({ text }) => text === '< ')).toBeDefined(); + }); + + test('should return range operators for date range fields', async () => { + const suggestions = await getSuggestions( + querySuggestionsArgs, + mockKueryNode({ fieldName: 'time_range' }) + ); + + expect(suggestions.find(({ text }) => text === ': ')).toBeDefined(); + expect(suggestions.find(({ text }) => text === '< ')).toBeDefined(); + }); + + test('should return range operators for ip range fields', async () => { + const suggestions = await getSuggestions( + querySuggestionsArgs, + mockKueryNode({ fieldName: 'ip_range' }) + ); + + expect(suggestions.find(({ text }) => text === ': ')).toBeDefined(); + expect(suggestions.find(({ text }) => text === '< ')).toBeDefined(); + }); + test('should have descriptions', async () => { const suggestions = await getSuggestions( querySuggestionsArgs, diff --git a/x-pack/plugins/data_enhanced/public/autocomplete/providers/kql_query_suggestion/operator.tsx b/x-pack/plugins/data_enhanced/public/autocomplete/providers/kql_query_suggestion/operator.tsx index 475aba63a8624..cfe935e4b1990 100644 --- a/x-pack/plugins/data_enhanced/public/autocomplete/providers/kql_query_suggestion/operator.tsx +++ b/x-pack/plugins/data_enhanced/public/autocomplete/providers/kql_query_suggestion/operator.tsx @@ -67,7 +67,18 @@ const operators = { 'xpack.data.kueryAutocomplete.equalOperatorDescription.equalsText' for 'equals' part." /> ), - fieldTypes: ['string', 'number', 'date', 'ip', 'geo_point', 'geo_shape', 'boolean'], + fieldTypes: [ + 'string', + 'number', + 'number_range', + 'date', + 'date_range', + 'ip', + 'ip_range', + 'geo_point', + 'geo_shape', + 'boolean', + ], }, '<=': { description: ( @@ -83,7 +94,7 @@ const operators = { 'xpack.data.kueryAutocomplete.lessThanOrEqualOperatorDescription.lessThanOrEqualToText' for 'less than or equal to' part." /> ), - fieldTypes: ['number', 'date', 'ip'], + fieldTypes: ['number', 'number_range', 'date', 'date_range', 'ip', 'ip_range'], }, '>=': { description: ( @@ -99,7 +110,7 @@ const operators = { 'xpack.data.kueryAutocomplete.greaterThanOrEqualOperatorDescription.greaterThanOrEqualToText' for 'greater than or equal to' part." /> ), - fieldTypes: ['number', 'date', 'ip'], + fieldTypes: ['number', 'number_range', 'date', 'date_range', 'ip', 'ip_range'], }, '<': { description: ( @@ -111,7 +122,7 @@ const operators = { 'xpack.data.kueryAutocomplete.lessThanOperatorDescription.lessThanText' for 'less than' part." /> ), - fieldTypes: ['number', 'date', 'ip'], + fieldTypes: ['number', 'number_range', 'date', 'date_range', 'ip', 'ip_range'], }, '>': { description: ( @@ -125,7 +136,7 @@ const operators = { 'xpack.data.kueryAutocomplete.greaterThanOperatorDescription.greaterThanText' for 'greater than' part." /> ), - fieldTypes: ['number', 'date', 'ip'], + fieldTypes: ['number', 'number_range', 'date', 'date_range', 'ip', 'ip_range'], }, ': *': { description: ( diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/datapanel.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/datapanel.tsx index e487e185a8c8f..6405309870f0c 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/datapanel.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/datapanel.tsx @@ -63,6 +63,9 @@ const supportedFieldTypes = new Set([ 'boolean', 'date', 'ip', + 'number_range', + 'date_range', + 'ip_range', 'histogram', 'document', ]); diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/field_item.test.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/field_item.test.tsx index 99b571af964fb..ac82d9d3c4363 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/field_item.test.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/field_item.test.tsx @@ -71,6 +71,13 @@ describe('IndexPattern Field Item', () => { aggregatable: true, searchable: true, }, + { + name: 'ip_range', + displayName: 'ip_range', + type: 'ip_range', + aggregatable: true, + searchable: true, + }, documentField, ], } as IndexPattern; @@ -234,4 +241,25 @@ describe('IndexPattern Field Item', () => { expect(wrapper.find(EuiPopover).prop('isOpen')).toEqual(true); expect(wrapper.find(EuiLoadingSpinner)).toHaveLength(0); }); + + it('should not request field stats for range fields', async () => { + const wrapper = mountWithIntl( + + ); + + await act(async () => { + clickField(wrapper, 'ip_range'); + }); + + expect(core.http.post).not.toHaveBeenCalled(); + }); }); diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/field_item.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/field_item.tsx index 5f8c13635025b..3b4940263c4bd 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/field_item.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/field_item.tsx @@ -122,7 +122,8 @@ export const InnerFieldItem = function InnerFieldItem(props: FieldItemProps) { }); function fetchData() { - if (state.isLoading || field.type === 'document') { + // Range types don't have any useful stats we can show + if (state.isLoading || field.type === 'document' || field.type.includes('range')) { return; } @@ -376,6 +377,18 @@ function FieldItemPopoverContents(props: State & FieldItemProps) { if (props.isLoading) { return ; + } else if (field.type.includes('range')) { + return ( + <> + {panelHeader} + + + {i18n.translate('xpack.lens.indexPattern.fieldStatsLimited', { + defaultMessage: `Summary information is not available for range type fields.`, + })} + + + ); } else if ( (!props.histogram || props.histogram.buckets.length === 0) && (!props.topValues || props.topValues.buckets.length === 0) diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern_suggestions.test.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern_suggestions.test.tsx index 1e928f1c0b2bf..210716e7494e0 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern_suggestions.test.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern_suggestions.test.tsx @@ -63,6 +63,13 @@ const fieldsOne = [ aggregatable: true, searchable: true, }, + { + name: 'bytes_range', + displayName: 'bytes_range', + type: 'number_range', + aggregatable: true, + searchable: true, + }, documentField, ]; diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/cardinality.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/cardinality.tsx index bd8f2a50ae216..80885a58e17f5 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/cardinality.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/cardinality.tsx @@ -13,7 +13,16 @@ import { FormattedIndexPatternColumn, FieldBasedIndexPatternColumn } from './col import { getFormatFromPreviousColumn, getInvalidFieldMessage, getSafeName } from './helpers'; -const supportedTypes = new Set(['string', 'boolean', 'number', 'ip', 'date']); +const supportedTypes = new Set([ + 'string', + 'boolean', + 'number', + 'number_range', + 'ip', + 'ip_range', + 'date', + 'date_range', +]); const SCALE = 'ratio'; const OPERATION_TYPE = 'cardinality'; diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/date_histogram.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/date_histogram.tsx index 4d4556a0ac4ad..8d40ed9b7f066 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/date_histogram.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/date_histogram.tsx @@ -63,7 +63,7 @@ export const dateHistogramOperation: OperationDefinition< getHelpMessage: (props) => , getPossibleOperationForField: ({ aggregationRestrictions, aggregatable, type }) => { if ( - type === 'date' && + (type === 'date' || type === 'date_range') && aggregatable && (!aggregationRestrictions || aggregationRestrictions.date_histogram) ) { diff --git a/x-pack/plugins/lens/server/routes/field_stats.ts b/x-pack/plugins/lens/server/routes/field_stats.ts index 57b3e59f4ad5c..3b293f9af7f28 100644 --- a/x-pack/plugins/lens/server/routes/field_stats.ts +++ b/x-pack/plugins/lens/server/routes/field_stats.ts @@ -93,6 +93,10 @@ export async function initFieldsRoute(setup: CoreSetup) { return result; }; + if (field.type.includes('range')) { + return res.ok({ body: {} }); + } + if (field.type === 'histogram') { return res.ok({ body: await getNumberHistogram(search, field, false), diff --git a/x-pack/test/api_integration/apis/lens/existing_fields.ts b/x-pack/test/api_integration/apis/lens/existing_fields.ts index 49e1ceb88164f..88949401f102a 100644 --- a/x-pack/test/api_integration/apis/lens/existing_fields.ts +++ b/x-pack/test/api_integration/apis/lens/existing_fields.ts @@ -45,6 +45,7 @@ const fieldsWithData = [ 'machine.os', 'machine.os.raw', 'machine.ram', + 'machine.ram_range', 'memory', 'phpmemory', 'referer', diff --git a/x-pack/test/functional/es_archives/logstash_functional/data.json.gz b/x-pack/test/functional/es_archives/logstash_functional/data.json.gz index 02195f888b93c..08d0c6e652352 100644 Binary files a/x-pack/test/functional/es_archives/logstash_functional/data.json.gz and b/x-pack/test/functional/es_archives/logstash_functional/data.json.gz differ diff --git a/x-pack/test/functional/es_archives/logstash_functional/mappings.json b/x-pack/test/functional/es_archives/logstash_functional/mappings.json index 12853523615bd..a7130076ed438 100644 --- a/x-pack/test/functional/es_archives/logstash_functional/mappings.json +++ b/x-pack/test/functional/es_archives/logstash_functional/mappings.json @@ -133,6 +133,9 @@ }, "ram": { "type": "long" + }, + "ram_range": { + "type": "long_range" } } },