-
Notifications
You must be signed in to change notification settings - Fork 8.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Enable include/exclude in Terms agg for numeric fields #59425
Conversation
Pinging @elastic/kibana-app (Team:KibanaApp) |
@elasticmachine merge upstream |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, tested locally in Chrome (Mac).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The difference isn't big:
NumberList
creates next value as incremented the last one,SimpleNumberList
creates just empty input;NumberList
saves an empty value asundefined
to value,SimpleNumberList
- as an empty string;NumberList
can influence on the form validity and it usesuseValidation
hook 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.
@@ -17,24 +17,26 @@ | |||
* under the License. | |||
*/ | |||
|
|||
import { isString, isObject } from 'lodash'; | |||
import { isString, isObject, isArray } from 'lodash'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎨 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.
@@ -44,7 +46,12 @@ export const migrateIncludeExcludeFormat = { | |||
) { | |||
const value = aggConfig.getParam(this.name); | |||
|
|||
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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
type
function to accept multiple type arguments, so it allows declaring other functions based on this one. For example,isStringOrNumberType
accepts bothstring
andnumber
types.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
IncludeExcludeParamEditor
that returns string or number list controls depending on the type ofagg
.isType
function inmigrate_include_exclude_format.ts
now 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:
isNumberType
function is used to check if the agg type is number.isStringOrNumberType
function is used inshouldShow
field oftermsBucketAgg
to check if the agg type is number or string.IncludeExcludeParamEditor
has props type ofAggParamEditorProps<string | Array<number | undefined>>
and returns eitherEuiFormRow
with multipleNumberRow
s orStringParamEditor
depending ofisNumberType(props.agg)
result.