mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 01:13:23 -04:00
Support for number, date and IP range data types (#76971)
* Support for number, date and IP ranges * Update tests * Ranges don't work with range agg * Fix test case * Allow Discover to create range filters * Supports ranges in Visualize, KQL, remove Lens support * Fix test mappings * Bring back field cache to work around bug * Fix some tests * Fix test expectation * Respond to review comments * Fix type error * Remove added sample data * Fix api_docs * Fix test
This commit is contained in:
parent
6b26d19c4c
commit
c33987d929
49 changed files with 532 additions and 59 deletions
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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": []
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
},
|
||||
|
|
|
@ -25,16 +25,22 @@ export declare enum ES_FIELD_TYPES
|
|||
| BYTE | <code>"byte"</code> | |
|
||||
| DATE | <code>"date"</code> | |
|
||||
| DATE\_NANOS | <code>"date_nanos"</code> | |
|
||||
| DATE\_RANGE | <code>"date_range"</code> | |
|
||||
| DOUBLE | <code>"double"</code> | |
|
||||
| DOUBLE\_RANGE | <code>"double_range"</code> | |
|
||||
| FLOAT | <code>"float"</code> | |
|
||||
| FLOAT\_RANGE | <code>"float_range"</code> | |
|
||||
| GEO\_POINT | <code>"geo_point"</code> | |
|
||||
| GEO\_SHAPE | <code>"geo_shape"</code> | |
|
||||
| HALF\_FLOAT | <code>"half_float"</code> | |
|
||||
| HISTOGRAM | <code>"histogram"</code> | |
|
||||
| INTEGER | <code>"integer"</code> | |
|
||||
| INTEGER\_RANGE | <code>"integer_range"</code> | |
|
||||
| IP | <code>"ip"</code> | |
|
||||
| IP\_RANGE | <code>"ip_range"</code> | |
|
||||
| KEYWORD | <code>"keyword"</code> | |
|
||||
| LONG | <code>"long"</code> | |
|
||||
| LONG\_RANGE | <code>"long_range"</code> | |
|
||||
| MURMUR3 | <code>"murmur3"</code> | |
|
||||
| NESTED | <code>"nested"</code> | |
|
||||
| OBJECT | <code>"object"</code> | |
|
||||
|
|
|
@ -21,13 +21,16 @@ export declare enum KBN_FIELD_TYPES
|
|||
| BOOLEAN | <code>"boolean"</code> | |
|
||||
| CONFLICT | <code>"conflict"</code> | |
|
||||
| DATE | <code>"date"</code> | |
|
||||
| DATE\_RANGE | <code>"date_range"</code> | |
|
||||
| GEO\_POINT | <code>"geo_point"</code> | |
|
||||
| GEO\_SHAPE | <code>"geo_shape"</code> | |
|
||||
| HISTOGRAM | <code>"histogram"</code> | |
|
||||
| IP | <code>"ip"</code> | |
|
||||
| IP\_RANGE | <code>"ip_range"</code> | |
|
||||
| MURMUR3 | <code>"murmur3"</code> | |
|
||||
| NESTED | <code>"nested"</code> | |
|
||||
| NUMBER | <code>"number"</code> | |
|
||||
| NUMBER\_RANGE | <code>"number_range"</code> | |
|
||||
| OBJECT | <code>"object"</code> | |
|
||||
| STRING | <code>"string"</code> | |
|
||||
| UNKNOWN | <code>"unknown"</code> | |
|
||||
|
|
|
@ -25,16 +25,22 @@ export declare enum ES_FIELD_TYPES
|
|||
| BYTE | <code>"byte"</code> | |
|
||||
| DATE | <code>"date"</code> | |
|
||||
| DATE\_NANOS | <code>"date_nanos"</code> | |
|
||||
| DATE\_RANGE | <code>"date_range"</code> | |
|
||||
| DOUBLE | <code>"double"</code> | |
|
||||
| DOUBLE\_RANGE | <code>"double_range"</code> | |
|
||||
| FLOAT | <code>"float"</code> | |
|
||||
| FLOAT\_RANGE | <code>"float_range"</code> | |
|
||||
| GEO\_POINT | <code>"geo_point"</code> | |
|
||||
| GEO\_SHAPE | <code>"geo_shape"</code> | |
|
||||
| HALF\_FLOAT | <code>"half_float"</code> | |
|
||||
| HISTOGRAM | <code>"histogram"</code> | |
|
||||
| INTEGER | <code>"integer"</code> | |
|
||||
| INTEGER\_RANGE | <code>"integer_range"</code> | |
|
||||
| IP | <code>"ip"</code> | |
|
||||
| IP\_RANGE | <code>"ip_range"</code> | |
|
||||
| KEYWORD | <code>"keyword"</code> | |
|
||||
| LONG | <code>"long"</code> | |
|
||||
| LONG\_RANGE | <code>"long_range"</code> | |
|
||||
| MURMUR3 | <code>"murmur3"</code> | |
|
||||
| NESTED | <code>"nested"</code> | |
|
||||
| OBJECT | <code>"object"</code> | |
|
||||
|
|
|
@ -21,13 +21,16 @@ export declare enum KBN_FIELD_TYPES
|
|||
| BOOLEAN | <code>"boolean"</code> | |
|
||||
| CONFLICT | <code>"conflict"</code> | |
|
||||
| DATE | <code>"date"</code> | |
|
||||
| DATE\_RANGE | <code>"date_range"</code> | |
|
||||
| GEO\_POINT | <code>"geo_point"</code> | |
|
||||
| GEO\_SHAPE | <code>"geo_shape"</code> | |
|
||||
| HISTOGRAM | <code>"histogram"</code> | |
|
||||
| IP | <code>"ip"</code> | |
|
||||
| IP\_RANGE | <code>"ip_range"</code> | |
|
||||
| MURMUR3 | <code>"murmur3"</code> | |
|
||||
| NESTED | <code>"nested"</code> | |
|
||||
| NUMBER | <code>"number"</code> | |
|
||||
| NUMBER\_RANGE | <code>"number_range"</code> | |
|
||||
| OBJECT | <code>"object"</code> | |
|
||||
| STRING | <code>"string"</code> | |
|
||||
| UNKNOWN | <code>"unknown"</code> | |
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
},
|
||||
];
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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;
|
||||
},
|
||||
|
|
|
@ -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;
|
||||
},
|
||||
|
|
|
@ -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: () => {},
|
||||
},
|
||||
|
|
|
@ -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],
|
||||
},
|
||||
{
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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', () => {
|
||||
|
|
|
@ -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 = {
|
||||
|
|
|
@ -42,6 +42,7 @@ class ValueInputTypeUI extends Component<Props> {
|
|||
);
|
||||
break;
|
||||
case 'number':
|
||||
case 'number_range':
|
||||
inputElement = (
|
||||
<EuiFieldNumber
|
||||
fullWidth={this.props.fullWidth}
|
||||
|
@ -54,6 +55,7 @@ class ValueInputTypeUI extends Component<Props> {
|
|||
);
|
||||
break;
|
||||
case 'date':
|
||||
case 'date_range':
|
||||
inputElement = (
|
||||
<EuiFieldText
|
||||
fullWidth={this.props.fullWidth}
|
||||
|
@ -68,6 +70,7 @@ class ValueInputTypeUI extends Component<Props> {
|
|||
);
|
||||
break;
|
||||
case 'ip':
|
||||
case 'ip_range':
|
||||
inputElement = (
|
||||
<EuiFieldText
|
||||
fullWidth={this.props.fullWidth}
|
||||
|
|
|
@ -329,10 +329,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",
|
||||
|
@ -347,12 +353,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",
|
||||
|
@ -1032,6 +1044,8 @@ export enum KBN_FIELD_TYPES {
|
|||
// (undocumented)
|
||||
DATE = "date",
|
||||
// (undocumented)
|
||||
DATE_RANGE = "date_range",
|
||||
// (undocumented)
|
||||
GEO_POINT = "geo_point",
|
||||
// (undocumented)
|
||||
GEO_SHAPE = "geo_shape",
|
||||
|
@ -1040,12 +1054,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",
|
||||
|
|
|
@ -117,6 +117,9 @@ export const fieldMappings = {
|
|||
ip: {
|
||||
type: 'ip',
|
||||
},
|
||||
ip_range: {
|
||||
type: 'ip_range',
|
||||
},
|
||||
timestamp: {
|
||||
type: 'date',
|
||||
},
|
||||
|
@ -124,6 +127,9 @@ export const fieldMappings = {
|
|||
type: 'alias',
|
||||
path: 'timestamp',
|
||||
},
|
||||
timestamp_range: {
|
||||
type: 'date_range',
|
||||
},
|
||||
phpmemory: {
|
||||
type: 'long',
|
||||
},
|
||||
|
|
|
@ -917,14 +917,26 @@ exports[`FieldEditor should show deprecated lang warning 1`] = `
|
|||
"text": "number",
|
||||
"value": "number",
|
||||
},
|
||||
Object {
|
||||
"text": "number_range",
|
||||
"value": "number_range",
|
||||
},
|
||||
Object {
|
||||
"text": "date",
|
||||
"value": "date",
|
||||
},
|
||||
Object {
|
||||
"text": "date_range",
|
||||
"value": "date_range",
|
||||
},
|
||||
Object {
|
||||
"text": "ip",
|
||||
"value": "ip",
|
||||
},
|
||||
Object {
|
||||
"text": "ip_range",
|
||||
"value": "ip_range",
|
||||
},
|
||||
Object {
|
||||
"text": "boolean",
|
||||
"value": "boolean",
|
||||
|
|
|
@ -65,6 +65,16 @@ exports[`FieldIcon renders known field types date is rendered 1`] = `
|
|||
/>
|
||||
`;
|
||||
|
||||
exports[`FieldIcon renders known field types date_range is rendered 1`] = `
|
||||
<EuiToken
|
||||
aria-label="date_range"
|
||||
className="kbnFieldIcon"
|
||||
iconType="tokenDate"
|
||||
size="s"
|
||||
title="date_range"
|
||||
/>
|
||||
`;
|
||||
|
||||
exports[`FieldIcon renders known field types geo_point is rendered 1`] = `
|
||||
<EuiToken
|
||||
aria-label="geo_point"
|
||||
|
@ -95,6 +105,16 @@ exports[`FieldIcon renders known field types ip is rendered 1`] = `
|
|||
/>
|
||||
`;
|
||||
|
||||
exports[`FieldIcon renders known field types ip_range is rendered 1`] = `
|
||||
<EuiToken
|
||||
aria-label="ip_range"
|
||||
className="kbnFieldIcon"
|
||||
iconType="tokenIP"
|
||||
size="s"
|
||||
title="ip_range"
|
||||
/>
|
||||
`;
|
||||
|
||||
exports[`FieldIcon renders known field types murmur3 is rendered 1`] = `
|
||||
<EuiToken
|
||||
aria-label="murmur3"
|
||||
|
@ -125,6 +145,16 @@ exports[`FieldIcon renders known field types number is rendered 1`] = `
|
|||
/>
|
||||
`;
|
||||
|
||||
exports[`FieldIcon renders known field types number_range is rendered 1`] = `
|
||||
<EuiToken
|
||||
aria-label="number_range"
|
||||
className="kbnFieldIcon"
|
||||
iconType="tokenNumber"
|
||||
size="s"
|
||||
title="number_range"
|
||||
/>
|
||||
`;
|
||||
|
||||
exports[`FieldIcon renders known field types string is rendered 1`] = `
|
||||
<EuiToken
|
||||
aria-label="string"
|
||||
|
|
|
@ -15,11 +15,14 @@ export interface FieldIconProps extends Omit<EuiTokenProps, 'iconType'> {
|
|||
| '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<Record<string, EuiTokenProps>> = {
|
|||
// 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' },
|
||||
|
|
|
@ -73,11 +73,12 @@ function NumberIntervalParamEditor({
|
|||
setValidity,
|
||||
setValue,
|
||||
}: AggParamEditorProps<string | undefined>) {
|
||||
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}`}
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
Binary file not shown.
|
@ -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 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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",
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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: (
|
||||
|
|
|
@ -63,6 +63,9 @@ const supportedFieldTypes = new Set([
|
|||
'boolean',
|
||||
'date',
|
||||
'ip',
|
||||
'number_range',
|
||||
'date_range',
|
||||
'ip_range',
|
||||
'histogram',
|
||||
'document',
|
||||
]);
|
||||
|
|
|
@ -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(
|
||||
<InnerFieldItem
|
||||
{...defaultProps}
|
||||
field={{
|
||||
name: 'ip_range',
|
||||
displayName: 'ip_range',
|
||||
type: 'ip_range',
|
||||
aggregatable: true,
|
||||
searchable: true,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
||||
await act(async () => {
|
||||
clickField(wrapper, 'ip_range');
|
||||
});
|
||||
|
||||
expect(core.http.post).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -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 <EuiLoadingSpinner />;
|
||||
} else if (field.type.includes('range')) {
|
||||
return (
|
||||
<>
|
||||
<EuiPopoverTitle>{panelHeader}</EuiPopoverTitle>
|
||||
|
||||
<EuiText size="s">
|
||||
{i18n.translate('xpack.lens.indexPattern.fieldStatsLimited', {
|
||||
defaultMessage: `Summary information is not available for range type fields.`,
|
||||
})}
|
||||
</EuiText>
|
||||
</>
|
||||
);
|
||||
} else if (
|
||||
(!props.histogram || props.histogram.buckets.length === 0) &&
|
||||
(!props.topValues || props.topValues.buckets.length === 0)
|
||||
|
|
|
@ -63,6 +63,13 @@ const fieldsOne = [
|
|||
aggregatable: true,
|
||||
searchable: true,
|
||||
},
|
||||
{
|
||||
name: 'bytes_range',
|
||||
displayName: 'bytes_range',
|
||||
type: 'number_range',
|
||||
aggregatable: true,
|
||||
searchable: true,
|
||||
},
|
||||
documentField,
|
||||
];
|
||||
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -63,7 +63,7 @@ export const dateHistogramOperation: OperationDefinition<
|
|||
getHelpMessage: (props) => <AutoDateHistogramPopover {...props} />,
|
||||
getPossibleOperationForField: ({ aggregationRestrictions, aggregatable, type }) => {
|
||||
if (
|
||||
type === 'date' &&
|
||||
(type === 'date' || type === 'date_range') &&
|
||||
aggregatable &&
|
||||
(!aggregationRestrictions || aggregationRestrictions.date_histogram)
|
||||
) {
|
||||
|
|
|
@ -93,6 +93,10 @@ export async function initFieldsRoute(setup: CoreSetup<PluginStartContract>) {
|
|||
return result;
|
||||
};
|
||||
|
||||
if (field.type.includes('range')) {
|
||||
return res.ok({ body: {} });
|
||||
}
|
||||
|
||||
if (field.type === 'histogram') {
|
||||
return res.ok({
|
||||
body: await getNumberHistogram(search, field, false),
|
||||
|
|
|
@ -45,6 +45,7 @@ const fieldsWithData = [
|
|||
'machine.os',
|
||||
'machine.os.raw',
|
||||
'machine.ram',
|
||||
'machine.ram_range',
|
||||
'memory',
|
||||
'phpmemory',
|
||||
'referer',
|
||||
|
|
Binary file not shown.
|
@ -133,6 +133,9 @@
|
|||
},
|
||||
"ram": {
|
||||
"type": "long"
|
||||
},
|
||||
"ram_range": {
|
||||
"type": "long_range"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue