Skip to content
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

[data.search.aggs] Remove fieldFormats from AggConfig & AggConfigs #69762

Merged
merged 9 commits into from
Jun 29, 2020

Conversation

lukeelmers
Copy link
Member

@lukeelmers lukeelmers commented Jun 23, 2020

(3 of 3)
Part of #65793

Summary

In #69114 and #69586 we gave AggConfigs the ability to return a serializable representation of the field format for the particular field the agg was using. This SerializedFieldFormat could then be passed to fieldFormats.deserialize so that downstream users could retrieve the actual format instance.

Since that feature has been introduced, there is no longer a need for an AggConfig to expose a way to retrieve the format instance for a particular field. Instead, anyone needing this should use toSerializedFieldFormat and deserialize as described above.

This also means that AggConfig no longer needs to depend directly on the fieldFormats service. (It does technically have an implicit dependency on field formats via indexPattern.fields.someField.format, but this has always been the case... ideally we would instead get the serialized field format off the index pattern instead).

Note that each of the AggTypes still do have a dependency on fieldFormats. This is something we should ideally refactor out eventually, but wasn't feasible to do here without a significant overhaul. The main barriers to removing formats from AggType are a few places where makeLabel and createFilter depend on field formats to format the values.

Items changed in this PR include:

  • remove fieldFormatter and fieldOwnFormatter from AggConfig
  • remove getFormat from all of the AggTypes
  • update table vis to work with the serialized field format
  • update buildTabularInspectorData to retrieve the field format via toSerializedFieldFormat and deserialize

Testing

This is simply a refactor of existing code and should introduce no functional changes. Areas to check for regressions are inspector and table vis. In the inspector, fields in the "data" tab should continue to have field formats applied as expected. In table vis, under the "options" tab, the Percentage Column dropdown should continue to only display numerical fields.

Dev Docs

AggConfig has been updated to no longer return a field format instance for the field it is aggregating on. As a result, the fieldFormatter and fieldOwnFormatter methods have been removed. Additionally, the getFormat method has been removed from each individual agg type.

If you need to access a field format instance, use the newly-added AggConfig.toSerializedFieldFormat, or AggType.toSerializedFormat to retrieve the serializable representation of the field's format, and then pass it to the deserialize method from the field formats service to get the actual format instance.

class MyPlugin {
  async start(core, { data }) {
    const { indexPatterns, fieldFormats, search } = data;
    const indexPattern = await indexPatterns.get('myId');
    const agg = {
      type: 'terms',
      params: { field: 'machine.os.keyword' },
    };
    const aggConfigs = search.aggs.createAggConfigs(indexPattern, [agg]);
    const termsAgg = aggConfigs.aggs[0];
-    const formatter = termsAgg.type.getFormat(termsAgg);
-    // or
-    const formatter = termsAgg.fieldFormatter('text');
+    const formatter = fieldFormats.deserialize(termsAgg.toSerializedFieldFormat());
+    // or
+    const formatter = fieldFormats.deserialize(termsAgg.type.getSerializedFormat(termsAgg));
     const formattedValue = formatter.convert('myValue');
  }
}

In addition, the legacy formatting helpers that were exported from ui/visualize/loader/pipeline_helpers/utilities have been removed. If your plugin imports from this directory, please update your code to use the fieldFormats service directly.

@lukeelmers lukeelmers added review Feature:Aggregations Aggregation infrastructure (AggConfig, esaggs, ...) release_note:plugin_api_changes Contains a Plugin API changes section for the breaking plugin API changes section. v8.0.0 Team:AppArch Feature:FieldFormatters v7.9.0 labels Jun 23, 2020
@lukeelmers lukeelmers self-assigned this Jun 23, 2020
Comment on lines +56 to +59
if (Object.keys(format).length < 1) {
// If no format exists, fall back to string as a default
format = { id: 'string' };
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This fallback behavior existed previously in agg.fieldFormatter() so we need to replicate it here or empty serialized formats ({}) don't receive any formatting, like - for an empty value.

Comment on lines +24 to +25
/** @internal */
export const createFilterHistogram = (getInternalStartServices: GetInternalStartServicesFn) => {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now that we don't have aggConfig.fieldFormatter, these need to be wrapped in a provider function so that getInternalStartServices can be passed in to access fieldFormats.deserialize instead. (This is also one of the reasons agg types still depend on field formats, even though agg configs & agg config doesn't)

expect(filter).toHaveProperty('range');
expect(filter).toHaveProperty('meta');
expect(filter.meta).toHaveProperty('index', '1234');
expect(filter.range).toHaveProperty('bytes');
expect(filter.range.bytes).toHaveProperty('gte', 1024.0);
expect(filter.range.bytes).toHaveProperty('lt', 2048.0);
expect(filter.meta).toHaveProperty('formattedValue', '≥ 1,024 and < 2,048');
expect(filter.meta).toHaveProperty('formattedValue');
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are no longer testing for specific values here since the mocks aren't returning any real values, but I don't think they were the right thing to test here anyway. Instead I'm just making sure a formattedValue is included, and also verifying that fieldFormats.deserialize was called as expected. Whether the values are deserialized correctly is something to test in field formats.

Comment on lines +39 to +42
deserialize: jest.fn().mockImplementation(() => {
const DefaultFieldFormat = FieldFormat.from(identity);
return new DefaultFieldFormat();
}),
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a mock implementation to improve these somewhat. I just stole this from the getFormat function inside of fieldFormats.deserialize.

Important to note that since this is configured with identity, any calls against this mock are just going to return whatever they are given. So you'll get a convert function you can use, but of course it won't actually convert what you give to it.

type: {
id: 'bytes',
},
toJSON: () => ({ id: 'bytes' }),
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These mocks were changed because this is basically the only part of field formats that AggConfig cares about: getting the serialized format for the field from the provided index pattern

@@ -54,6 +54,7 @@ export const getGeoHashBucketAgg = ({ getInternalStartServices }: GeoHashBucketA
{
name: BUCKET_TYPES.GEOHASH_GRID,
title: geohashGridTitle,
makeLabel: () => geohashGridTitle,
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Though not directly related to the other items in this PR, I added these makeLabel methods to geo hash & filter aggs in this PR because I noticed they were missing, which causes column headers to be unformatted in the inspector.

@lukeelmers

This comment has been minimized.

@elasticmachine

This comment has been minimized.

@lukeelmers lukeelmers force-pushed the fix/remove-agg-formats branch from bf8e6de to b035324 Compare June 24, 2020 19:18
@lukeelmers lukeelmers marked this pull request as ready for review June 24, 2020 22:33
@lukeelmers lukeelmers requested a review from a team June 24, 2020 22:33
@lukeelmers lukeelmers requested a review from a team as a code owner June 24, 2020 22:33
@elasticmachine
Copy link
Contributor

Pinging @elastic/kibana-app-arch (Team:AppArch)

Copy link
Contributor

@flash1293 flash1293 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested the change in table vis - the percentage column dropdown is still populated correctly. LGTM

Didn't do a thorough code review of the app arch code.

Copy link
Member

@kertal kertal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

KibanaApp owned code looks beautiful, table viz still works (tested in Chrome) ... finishing this review even @flash1293 overtook while had to take care of child logistics 🧒 -> 🐘 :)

@lukeelmers

This comment has been minimized.

Copy link
Member

@ppisljar ppisljar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

code LGTM

@lukeelmers
Copy link
Member Author

@elasticmachine merge upstream

@kibanamachine
Copy link
Contributor

💚 Build Succeeded

Build metrics

page load asset size

beta
id value diff baseline
/bundles/app/core/bootstrap.js - -13.9KB 13.9KB
/bundles/core/core.entry.js - -1.1MB 1.1MB
/bundles/kbn-ui-shared-deps/[email protected] - -4.0MB 4.0MB
/bundles/kbn-ui-shared-deps/kbn-ui-shared-deps.css - -183.7KB 183.7KB
/bundles/kbn-ui-shared-deps/kbn-ui-shared-deps.js - -4.6MB 4.6MB
/bundles/kbn-ui-shared-deps/kbn-ui-shared-deps.v7.light.css - -511.3KB 511.3KB
/bundles/light_theme.style.css - -95.9KB 95.9KB
/bundles/plugin/advancedSettings/advancedSettings.plugin.js - -941.3KB 941.3KB
/bundles/plugin/alerts/alerts.plugin.js - -89.5KB 89.5KB
/bundles/plugin/apm/apm.plugin.js - -219.2KB 219.2KB
/bundles/plugin/apmOss/apmOss.plugin.js - -4.2KB 4.2KB
/bundles/plugin/beats_management/beats_management.plugin.js - -522.9KB 522.9KB
/bundles/plugin/bfetch/bfetch.plugin.js - -28.7KB 28.7KB
/bundles/plugin/canvas/canvas.plugin.js - -2.0MB 2.0MB
/bundles/plugin/charts/charts.plugin.js - -833.9KB 833.9KB
/bundles/plugin/cloud/cloud.plugin.js - -6.2KB 6.2KB
/bundles/plugin/console/console.plugin.js - -28.0KB 28.0KB
/bundles/plugin/crossClusterReplication/crossClusterReplication.plugin.js - -152.3KB 152.3KB
/bundles/plugin/dashboard/dashboard.plugin.js - -634.2KB 634.2KB
/bundles/plugin/dashboardEnhanced/dashboardEnhanced.plugin.js - -143.5KB 143.5KB
/bundles/plugin/dashboardMode/dashboardMode.plugin.js - -109.3KB 109.3KB
/bundles/plugin/data/data.plugin.js - -1.3MB 1.3MB
/bundles/plugin/dataEnhanced/dataEnhanced.plugin.js - -138.1KB 138.1KB
/bundles/plugin/devTools/devTools.plugin.js - -123.9KB 123.9KB
/bundles/plugin/discover/discover.plugin.js - -221.5KB 221.5KB
/bundles/plugin/discoverEnhanced/discoverEnhanced.plugin.js - -28.1KB 28.1KB
/bundles/plugin/embeddable/embeddable.plugin.js - -390.9KB 390.9KB
/bundles/plugin/embeddableEnhanced/embeddableEnhanced.plugin.js - -26.3KB 26.3KB
/bundles/plugin/esUiShared/esUiShared.plugin.js - -927.8KB 927.8KB
/bundles/plugin/expressions/expressions.plugin.js - -314.9KB 314.9KB
/bundles/plugin/features/features.plugin.js - -13.4KB 13.4KB
/bundles/plugin/fileUpload/fileUpload.plugin.js - -688.0KB 688.0KB
/bundles/plugin/globalSearch/globalSearch.plugin.js - -29.0KB 29.0KB
/bundles/plugin/globalSearchProviders/globalSearchProviders.plugin.js - -9.7KB 9.7KB
/bundles/plugin/graph/graph.plugin.js - -15.3KB 15.3KB
/bundles/plugin/grokdebugger/grokdebugger.plugin.js - -11.2KB 11.2KB
/bundles/plugin/home/home.plugin.js - -24.6KB 24.6KB
/bundles/plugin/indexLifecycleManagement/indexLifecycleManagement.plugin.js - -184.2KB 184.2KB
/bundles/plugin/indexManagement/indexManagement.plugin.js - -201.7KB 201.7KB
/bundles/plugin/indexPatternManagement/indexPatternManagement.plugin.js - -137.3KB 137.3KB
/bundles/plugin/infra/infra.plugin.js - -92.9KB 92.9KB
/bundles/plugin/ingestPipelines/ingestPipelines.plugin.js - -30.8KB 30.8KB
/bundles/plugin/inputControlVis/inputControlVis.plugin.js - -258.9KB 258.9KB
/bundles/plugin/inspector/inspector.plugin.js - -238.3KB 238.3KB
/bundles/plugin/kibanaLegacy/kibanaLegacy.plugin.js - -174.7KB 174.7KB
/bundles/plugin/kibanaReact/kibanaReact.plugin.js - -575.3KB 575.3KB
/bundles/plugin/kibanaUtils/kibanaUtils.plugin.js - -434.4KB 434.4KB
/bundles/plugin/lens/lens.plugin.js - -758.3KB 758.3KB
/bundles/plugin/licenseManagement/licenseManagement.plugin.js - -25.8KB 25.8KB
/bundles/plugin/licensing/licensing.plugin.js - -21.6KB 21.6KB
/bundles/plugin/logstash/logstash.plugin.js - -141.8KB 141.8KB
/bundles/plugin/management/management.plugin.js - -25.9KB 25.9KB
/bundles/plugin/maps/maps.plugin.js - -220.6KB 220.6KB
/bundles/plugin/mapsLegacy/mapsLegacy.plugin.js - -1.0MB 1.0MB
/bundles/plugin/mapsLegacyLicensing/mapsLegacyLicensing.plugin.js - -3.9KB 3.9KB
/bundles/plugin/ml/ml.plugin.js - -1.3MB 1.3MB
/bundles/plugin/monitoring/monitoring.plugin.js - -22.8KB 22.8KB
/bundles/plugin/navigation/navigation.plugin.js - -122.2KB 122.2KB
/bundles/plugin/newsfeed/newsfeed.plugin.js - -22.7KB 22.7KB
/bundles/plugin/observability/observability.plugin.js - -103.1KB 103.1KB
/bundles/plugin/painlessLab/painlessLab.plugin.js - -158.8KB 158.8KB
/bundles/plugin/regionMap/regionMap.plugin.js - -791.7KB 791.7KB
/bundles/plugin/remoteClusters/remoteClusters.plugin.js - -35.2KB 35.2KB
/bundles/plugin/reporting/reporting.plugin.js - -257.7KB 257.7KB
/bundles/plugin/rollup/rollup.plugin.js - -186.0KB 186.0KB
/bundles/plugin/savedObjects/savedObjects.plugin.js - -196.2KB 196.2KB
/bundles/plugin/savedObjectsManagement/savedObjectsManagement.plugin.js - -176.6KB 176.6KB
/bundles/plugin/searchprofiler/searchprofiler.plugin.js - -42.8KB 42.8KB
/bundles/plugin/security/security.plugin.js - -248.0KB 248.0KB
/bundles/plugin/share/share.plugin.js - -80.5KB 80.5KB
/bundles/plugin/snapshotRestore/snapshotRestore.plugin.js - -57.5KB 57.5KB
/bundles/plugin/spaces/spaces.plugin.js - -367.2KB 367.2KB
/bundles/plugin/statusPage/statusPage.plugin.js - -3.6KB 3.6KB
/bundles/plugin/telemetry/telemetry.plugin.js - -77.0KB 77.0KB
/bundles/plugin/telemetryManagementSection/telemetryManagementSection.plugin.js - -27.5KB 27.5KB
/bundles/plugin/tileMap/tileMap.plugin.js - -807.1KB 807.1KB
/bundles/plugin/transform/transform.plugin.js - -21.6KB 21.6KB
/bundles/plugin/triggers_actions_ui/triggers_actions_ui.plugin.js - -103.0KB 103.0KB
/bundles/plugin/uiActions/uiActions.plugin.js - -162.5KB 162.5KB
/bundles/plugin/uiActionsEnhanced/uiActionsEnhanced.plugin.js - -130.7KB 130.7KB
/bundles/plugin/upgradeAssistant/upgradeAssistant.plugin.js - -46.6KB 46.6KB
/bundles/plugin/uptime/uptime.plugin.js - -327.3KB 327.3KB
/bundles/plugin/usageCollection/usageCollection.plugin.js - -24.4KB 24.4KB
/bundles/plugin/visTypeMarkdown/visTypeMarkdown.plugin.js - -512.5KB 512.5KB
/bundles/plugin/visTypeMetric/visTypeMetric.plugin.js - -536.7KB 536.7KB
/bundles/plugin/visTypeTable/visTypeTable.plugin.js - -563.0KB 563.0KB
/bundles/plugin/visTypeTagcloud/visTypeTagcloud.plugin.js - -797.1KB 797.1KB
/bundles/plugin/visTypeTimelion/visTypeTimelion.plugin.js - -670.7KB 670.7KB
/bundles/plugin/visTypeTimeseries/visTypeTimeseries.plugin.js - -212.2KB 212.2KB
/bundles/plugin/visTypeVega/visTypeVega.plugin.js - -580.3KB 580.3KB
/bundles/plugin/visTypeVislib/visTypeVislib.plugin.js - -1.2MB 1.2MB
/bundles/plugin/visualizations/visualizations.plugin.js - -343.4KB 343.4KB
/bundles/plugin/visualize/visualize.plugin.js - -18.2KB 18.2KB
/bundles/plugin/watcher/watcher.plugin.js - -35.2KB 35.2KB
/node_modules/@kbn/ui-framework/dist/kui_light.css - -62.1KB 62.1KB
/translations/en.json - -29.0B 29.0B
/ui/fonts/inter_ui/Inter-UI-Medium.woff2 - -92.2KB 92.2KB
/ui/fonts/inter_ui/Inter-UI-Regular.woff2 - -86.4KB 86.4KB
total - -36.2MB -

History

To update your PR or re-run it, just comment with:
@elasticmachine merge upstream

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Feature:Aggregations Aggregation infrastructure (AggConfig, esaggs, ...) Feature:FieldFormatters release_note:plugin_api_changes Contains a Plugin API changes section for the breaking plugin API changes section. review v7.9.0 v8.0.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants