Enable include/exclude in Terms agg for numeric fields#59425
Enable include/exclude in Terms agg for numeric fields#59425DianaDerevyankina merged 31 commits intoelastic:masterfrom
Conversation
|
Pinging @elastic/kibana-app (Team:KibanaApp) |
|
@elasticmachine merge upstream |
maryia-lapata
left a comment
There was a problem hiding this comment.
LGTM, tested locally in Chrome (Mac).
timroes
left a comment
There was a problem hiding this comment.
Unfortunately that PR does not quiet work yet. The include/exclude fields are shown for numeric types now, but they actually don't work, because their values are never written to the request for numerical types.
This is prevented by the check in migrate_include_exclude_format.ts line 50, which actually only writes them to the output if the field is of type string. Also we cannot simply write out a the string as it is for numerical fields, since Elasticsearch does not accept a regex for numeric fields, but needs an array of numeric values. I'd suggest we just take the value inside the field, and split it by comma into an array, so the function would look like the following:
const isNumberType = isType('number');
// ....
if (isObject(value)) {
output.params[this.name] = value.pattern;
} else if (value && isStringType(aggConfig)) {
output.params[this.name] = value;
} else if (value.length > 0 && isNumberType(aggConfig)) {
output.params[this.name] = value
.split(',')
.map(val => Number(val.trim()))
.filter(val => !Number.isNaN(val));
}We should also add a couple of tests in terms.test.ts to make sure that the write method works correctly for numeric fields.
|
@timroes can include/exclude value for number type field be a decimal numeral? If yes, the decimal separator can be a point or a comma depending on the locale. Maybe a space can be a delimiter for number. |
|
@maryia-lapata It could potentially be a decimal number, but it would always need to be in the english format, since that is what the ES API takes. But I would also be fine if we're using e.g. semicolon as a separator if that feels better. To be honest in the long term I think the field should actually render as a numerical list (like we use in range aggregations, where you can add and remove input boxes and each just takes one number), but this would require way more changes (basically include/exclude need their own control separate from the
I totally agree with you. I think for doing that we already need our own editor control for include/exclude (since we cannot attach a tooltip to a generic |
|
@timroes I think since we're touching this Exclude/Include field, it's worth doing it in way it should be (with separate numerical list for number field type), which will be clear for a user. |
# Conflicts: # src/legacy/core_plugins/data/public/search/aggs/buckets/terms.ts
maryia-lapata
left a comment
There was a problem hiding this comment.
Great work!
In general LGTM, but it'd be nice to fix the comments below.
I tested on Chrome (Mac) the cases of switching field type, discarding, empty and invalid values (they are not in the request).
src/plugins/vis_default_editor/public/components/controls/include_exclude.tsx
Outdated
Show resolved
Hide resolved
src/plugins/vis_default_editor/public/components/controls/components/simple_number_list.tsx
Show resolved
Hide resolved
src/plugins/vis_default_editor/public/components/controls/components/simple_number_list.tsx
Outdated
Show resolved
Hide resolved
src/plugins/vis_default_editor/public/components/controls/components/simple_number_list.tsx
Outdated
Show resolved
Hide resolved
src/plugins/vis_default_editor/public/components/controls/components/simple_number_list.tsx
Outdated
Show resolved
Hide resolved
src/plugins/vis_default_editor/public/components/controls/components/simple_number_list.tsx
Outdated
Show resolved
Hide resolved
src/plugins/vis_default_editor/public/components/controls/components/simple_number_list.tsx
Outdated
Show resolved
Hide resolved
src/plugins/vis_default_editor/public/components/controls/components/simple_number_list.tsx
Outdated
Show resolved
Hide resolved
src/plugins/vis_default_editor/public/components/controls/include_exclude.tsx
Outdated
Show resolved
Hide resolved
# Conflicts: # src/plugins/data/public/public.api.md
|
|
||
| const generateId = htmlIdGenerator(); | ||
|
|
||
| function SimpleNumberList({ |
There was a problem hiding this comment.
@maryia-lapata @DianaDerevyankina Could you please explain shortly what's the different between SimpleNumberList and NumberList, we use in other places in the editor (like percentiles)? Is the difference really large enough that it justifies having a separate component, or were there just minor things, that we could potentially solve adding a property to NumberList?
There was a problem hiding this comment.
The difference isn't big:
NumberListcreates next value as incremented the last one,SimpleNumberListcreates just empty input;NumberListsaves an empty value asundefinedto value,SimpleNumberList- as an empty string;NumberListcan influence on the form validity and it usesuseValidationhook as well as it validates each input,SimpleNumberList- not;- there is no initial value in
SimpleNumberList.
In case we decide to reuse NumberList, it's needed to make it more generic. I think the component is already a bit complex (I wouldn't want to make it a magic component), and I'd leave a separate SimpleNumberList component.
| */ | ||
|
|
||
| import { isString, isObject } from 'lodash'; | ||
| import { isString, isObject, isArray } from 'lodash'; |
There was a problem hiding this comment.
🎨 We're trying to not introduce new lodash code if there is an easy vanilla JS equivalent. So I would recommend using Array.isArray instead of using a lodash function.
|
|
||
| if (isObject(value)) { | ||
| if (isArray(value) && value.length > 0 && isNumberType(aggConfig)) { | ||
| const parsedValue = (value as number[]).filter((val: number) => val || val === 0); |
There was a problem hiding this comment.
| const parsedValue = (value as number[]).filter((val: number) => val || val === 0); | |
| const parsedValue = value.filter((val): val is number => Number.isFinite(val)); |
This way we don't need to have a cast (as) in here, which always contains the danger of breaking in the future, since we "disabled" the type system in this place.
Using a custom typeguard val is number will tell typescript if that boolean returning function returns true, it is a number, otherwise not. That will lead to the same effect of parsedValue being actually a number[] in the end.
Also I would shorten the call for val || val === 0 to Number.isFinite since it's actually a bit safe, since it will only let numbers through, that are not NaN or Infinite, which is kind of similar to what you wanted to express here (except that val || val === 0 would potentially also let any string through).
| const numberArray = value | ||
| .split(',') | ||
| .map(item => parseFloat(item)) | ||
| .filter(number => !isNaN(number)); |
There was a problem hiding this comment.
I would use Number.isFinite here too, since we also wouldn't want Infinity to pass this check. Currently if you had Infinity in your string include/exclude it would show up as an empty input box after selecting a number field.
| .filter(number => !isNaN(number)); | ||
| setValue(numberArray.length ? numberArray : ['']); | ||
| } else if (!isAggOfNumberType && isArray(value) && value !== undefined) { | ||
| setValue((value as Array<number | ''>).filter(item => item !== '').toString()); |
There was a problem hiding this comment.
The case should not be needed here, TypeScript should know that value can only be Array<number | ''> due to the check in the if.
There was a problem hiding this comment.
Also toString() -> join('|') to align with the comment above.
| useEffect(() => { | ||
| if (isAggOfNumberType && !isArray(value) && value !== undefined) { | ||
| const numberArray = value | ||
| .split(',') |
There was a problem hiding this comment.
I think we want to use | for splitting here, since in the string version it was an regex and so a separator between different options would have had to be an | and a comma would just be part of the string matched.
…nged symbol of string join and array split
|
@elasticmachine merge upstream |
timroes
left a comment
There was a problem hiding this comment.
Tested on Chrome Linux, seems to work and being a really nice experience for numerical fields (way better then just one text field). Code LGTM
lukeelmers
left a comment
There was a problem hiding this comment.
Overall this looks great & is a nice addition! Tested locally on Chrome (macOS), and everything is working as I'd expect.
Reviewing the code, I primarily focused on the changes in data.search.aggs. No major concerns, although I would like to +1 Tim's earlier suggestion to add a few unit tests to terms.test.ts, just to make sure we don't forget this change in the future.
Aside from that, everything LGTM!
lukeelmers
left a comment
There was a problem hiding this comment.
Thanks for adding those tests! This LGTM once a green build comes back.
# Conflicts: # src/plugins/data/public/public.api.md
💚 Build SucceededHistory
To update your PR or re-run it, just comment with: |
* master: (30 commits) Migrate vis_type_table to kibana/new platform (elastic#63105) Enable include/exclude in Terms agg for numeric fields (elastic#59425) follow conventions for saved object definitions (elastic#63571) [Docs]Adds saved object key setting to load balancing kib instances (elastic#63935) kbn/config-schema: Consider maybe properties as optional keys in ObjectType (elastic#63838) Fix page layouts, clean up unused code (elastic#63992) [SIEM] Adds recursive exact key checks for validation and formatter [Maps] Migrate remaining maps client files to NP (except routi… (elastic#63859) [Maps] Do not fetch geo_shape from docvalues (elastic#63997) Vega doc changes (elastic#63889) [Metrics UI] Reorganize file layout for Metrics UI (elastic#60049) Add sub-menus to Resolver node (for 75% zoom) (elastic#63476) [FTR] Add test suite metrics tracking/output (elastic#62515) [ML] Fixing single metric viewer page padding (elastic#63839) [Discover] Allow user to generate a report after saving a modified saved search (elastic#63623) [Reporting] Config flag to escape formula CSV values (elastic#63645) [Metrics UI] Remove remaining field filtering (elastic#63398) [Maps] fix date labels (elastic#63909) [TSVB] Use default Kibana palette for split series (elastic#62241) Ingest overview page (elastic#63214) ...
* Enable include/exclude in Terms agg for numeric fields Closes elastic#4576 * Added a new component that allows adding multiple values * Added some validation to include/exclude fields * Removed unnecessary comments and accepted API changes * Fixed i18n ID issue * Refactored some code and fixed discard button issue * Added SimpleNumberList component and value parsing in include_exclude.tsx * Fixed merge conflict * Fixed merge conflict * Refactored some code * Got rid of lodash isArray, added Number.isFinite where needed and changed symbol of string join and array split * Added some more test cases to cover migrate_include_exclude_format write method Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
…t-node-pipelines * 'master' of github.com:elastic/kibana: (32 commits) Move authz lib out of snapshot restore (#63947) Migrate vis_type_table to kibana/new platform (#63105) Enable include/exclude in Terms agg for numeric fields (#59425) follow conventions for saved object definitions (#63571) [Docs]Adds saved object key setting to load balancing kib instances (#63935) kbn/config-schema: Consider maybe properties as optional keys in ObjectType (#63838) Fix page layouts, clean up unused code (#63992) [SIEM] Adds recursive exact key checks for validation and formatter [Maps] Migrate remaining maps client files to NP (except routi… (#63859) [Maps] Do not fetch geo_shape from docvalues (#63997) Vega doc changes (#63889) [Metrics UI] Reorganize file layout for Metrics UI (#60049) Add sub-menus to Resolver node (for 75% zoom) (#63476) [FTR] Add test suite metrics tracking/output (#62515) [ML] Fixing single metric viewer page padding (#63839) [Discover] Allow user to generate a report after saving a modified saved search (#63623) [Reporting] Config flag to escape formula CSV values (#63645) [Metrics UI] Remove remaining field filtering (#63398) [Maps] fix date labels (#63909) [TSVB] Use default Kibana palette for split series (#62241) ...
…bana into ingest-node-pipelines/privileges * 'feature/ingest-node-pipelines' of github.com:elastic/kibana: (34 commits) Move authz lib out of snapshot restore (elastic#63947) Migrate vis_type_table to kibana/new platform (elastic#63105) Enable include/exclude in Terms agg for numeric fields (elastic#59425) follow conventions for saved object definitions (elastic#63571) [Docs]Adds saved object key setting to load balancing kib instances (elastic#63935) kbn/config-schema: Consider maybe properties as optional keys in ObjectType (elastic#63838) Fix page layouts, clean up unused code (elastic#63992) [SIEM] Adds recursive exact key checks for validation and formatter [Maps] Migrate remaining maps client files to NP (except routi… (elastic#63859) [Maps] Do not fetch geo_shape from docvalues (elastic#63997) Vega doc changes (elastic#63889) [Metrics UI] Reorganize file layout for Metrics UI (elastic#60049) Add sub-menus to Resolver node (for 75% zoom) (elastic#63476) [FTR] Add test suite metrics tracking/output (elastic#62515) [Ingest pipelines] Delete pipeline (elastic#63635) [ML] Fixing single metric viewer page padding (elastic#63839) [Discover] Allow user to generate a report after saving a modified saved search (elastic#63623) [Reporting] Config flag to escape formula CSV values (elastic#63645) [Metrics UI] Remove remaining field filtering (elastic#63398) [Maps] fix date labels (elastic#63909) ... # Conflicts: # x-pack/legacy/plugins/uptime/public/components/monitor/ml/index.ts # x-pack/legacy/plugins/uptime/public/components/overview/index.ts # x-pack/plugins/ingest_pipelines/public/application/index.tsx # x-pack/plugins/ingest_pipelines/server/routes/api/index.ts # x-pack/plugins/ingest_pipelines/server/routes/index.ts
* Enable include/exclude in Terms agg for numeric fields Closes #4576 * Added a new component that allows adding multiple values * Added some validation to include/exclude fields * Removed unnecessary comments and accepted API changes * Fixed i18n ID issue * Refactored some code and fixed discard button issue * Added SimpleNumberList component and value parsing in include_exclude.tsx * Fixed merge conflict * Fixed merge conflict * Refactored some code * Got rid of lodash isArray, added Number.isFinite where needed and changed symbol of string join and array split * Added some more test cases to cover migrate_include_exclude_format write method Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com> Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
…bana into pipeline-editor-part-mvp-2 * 'feature/ingest-node-pipelines' of github.com:elastic/kibana: (34 commits) [Ingest Node Pipelines] Clone Pipeline (elastic#64049) Move authz lib out of snapshot restore (elastic#63947) Migrate vis_type_table to kibana/new platform (elastic#63105) Enable include/exclude in Terms agg for numeric fields (elastic#59425) follow conventions for saved object definitions (elastic#63571) [Docs]Adds saved object key setting to load balancing kib instances (elastic#63935) kbn/config-schema: Consider maybe properties as optional keys in ObjectType (elastic#63838) Fix page layouts, clean up unused code (elastic#63992) [SIEM] Adds recursive exact key checks for validation and formatter [Maps] Migrate remaining maps client files to NP (except routi… (elastic#63859) [Maps] Do not fetch geo_shape from docvalues (elastic#63997) Vega doc changes (elastic#63889) [Metrics UI] Reorganize file layout for Metrics UI (elastic#60049) Add sub-menus to Resolver node (for 75% zoom) (elastic#63476) [FTR] Add test suite metrics tracking/output (elastic#62515) [Ingest pipelines] Delete pipeline (elastic#63635) [ML] Fixing single metric viewer page padding (elastic#63839) [Discover] Allow user to generate a report after saving a modified saved search (elastic#63623) [Reporting] Config flag to escape formula CSV values (elastic#63645) [Metrics UI] Remove remaining field filtering (elastic#63398) ...
Closes #4576
Summary
Refactored
typefunction to accept multiple type arguments, so it allows declaring other functions based on this one. For example,isStringOrNumberTypeaccepts bothstringandnumbertypes.Added a possibility to write an array of numbers in request params.
Added a new Include/Exclude control that can accept either string or multiple numbers value.
Screenshots:
Dev-Docs
Added a new component
IncludeExcludeParamEditorthat returns string or number list controls depending on the type ofagg.isTypefunction inmigrate_include_exclude_format.tsnow can accept an array of string types that allows checking if a value has a type of any of those passed in the array.Based on this function, added 2 another:
isNumberTypefunction is used to check if the agg type is number.isStringOrNumberTypefunction is used inshouldShowfield oftermsBucketAggto check if the agg type is number or string.IncludeExcludeParamEditorhas props type ofAggParamEditorProps<string | Array<number | undefined>>and returns eitherEuiFormRowwith multipleNumberRows orStringParamEditordepending ofisNumberType(props.agg)result.