forked from elastic/kibana
/
cardinality.tsx
129 lines (118 loc) · 3.97 KB
/
cardinality.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import { i18n } from '@kbn/i18n';
import { AggFunctionsMapping } from '../../../../../../../src/plugins/data/public';
import { buildExpressionFunction } from '../../../../../../../src/plugins/expressions/public';
import { OperationDefinition } from './index';
import { FormattedIndexPatternColumn, FieldBasedIndexPatternColumn } from './column_types';
import {
getFormatFromPreviousColumn,
getInvalidFieldMessage,
getSafeName,
getFilter,
} from './helpers';
const supportedTypes = new Set([
'string',
'boolean',
'number',
'number_range',
'ip',
'ip_range',
'date',
'date_range',
]);
const SCALE = 'ratio';
const OPERATION_TYPE = 'unique_count';
const IS_BUCKETED = false;
function ofName(name: string) {
return i18n.translate('xpack.lens.indexPattern.cardinalityOf', {
defaultMessage: 'Unique count of {name}',
values: {
name,
},
});
}
export interface CardinalityIndexPatternColumn
extends FormattedIndexPatternColumn,
FieldBasedIndexPatternColumn {
operationType: typeof OPERATION_TYPE;
}
export const cardinalityOperation: OperationDefinition<CardinalityIndexPatternColumn, 'field'> = {
type: OPERATION_TYPE,
displayName: i18n.translate('xpack.lens.indexPattern.cardinality', {
defaultMessage: 'Unique count',
}),
input: 'field',
getPossibleOperationForField: ({ aggregationRestrictions, aggregatable, type }) => {
if (
supportedTypes.has(type) &&
aggregatable &&
(!aggregationRestrictions || aggregationRestrictions.cardinality)
) {
return { dataType: 'number', isBucketed: IS_BUCKETED, scale: SCALE };
}
},
getErrorMessage: (layer, columnId, indexPattern) =>
getInvalidFieldMessage(layer.columns[columnId] as FieldBasedIndexPatternColumn, indexPattern),
isTransferable: (column, newIndexPattern) => {
const newField = newIndexPattern.getFieldByName(column.sourceField);
return Boolean(
newField &&
supportedTypes.has(newField.type) &&
newField.aggregatable &&
(!newField.aggregationRestrictions || newField.aggregationRestrictions.cardinality)
);
},
filterable: true,
operationParams: [
{ name: 'kql', type: 'string', required: false },
{ name: 'lucene', type: 'string', required: false },
],
getDefaultLabel: (column, indexPattern) => ofName(getSafeName(column.sourceField, indexPattern)),
buildColumn({ field, previousColumn }, columnParams) {
return {
label: ofName(field.displayName),
dataType: 'number',
operationType: OPERATION_TYPE,
scale: SCALE,
sourceField: field.name,
isBucketed: IS_BUCKETED,
filter: getFilter(previousColumn, columnParams),
params: getFormatFromPreviousColumn(previousColumn),
};
},
toEsAggsFn: (column, columnId) => {
return buildExpressionFunction<AggFunctionsMapping['aggCardinality']>('aggCardinality', {
id: columnId,
enabled: true,
schema: 'metric',
field: column.sourceField,
}).toAst();
},
onFieldChange: (oldColumn, field) => {
return {
...oldColumn,
label: ofName(field.displayName),
sourceField: field.name,
};
},
documentation: {
section: 'elasticsearch',
signature: i18n.translate('xpack.lens.indexPattern.cardinality.signature', {
defaultMessage: 'field: string',
}),
description: i18n.translate('xpack.lens.indexPattern.cardinality.documentation', {
defaultMessage: `
Calculates the number of unique values of a specified field. Works for number, string, date and boolean values.
Example: Calculate the number of different products:
\`unique_count(product.name)\`
Example: Calculate the number of different products from the "clothes" group:
\`unique_count(product.name, kql='product.group=clothes')\`
`,
}),
},
};