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

[ES|QL] Add ECS information to the editor hint & prioritize fields based on ECS information on the editor #187922

Merged
merged 19 commits into from
Jul 15, 2024

Conversation

qn895
Copy link
Member

@qn895 qn895 commented Jul 9, 2024

Summary

Closes #181036. This PR adds ECS information to the editor hint & prioritizes fields based on ECS information on the editor. The logic involves:

  1. Identify if dataset has ecs fields (e.g. column contains ecs.version)
  2. If yes, check which fields have ecs info using fieldsMetadata client
  3. Push fields with ecs info up to the top of the list of suggestions and order these fields alphabetically. These pushed fields have "1D" sort text.
  4. Show the rest of the fields without ecs decription at the bottom, order these fields alphabetically.
Screen.Recording.2024-07-11.at.12.27.00.mov

Note for reviewers:

  • When fetching fields metadata, if there are many fields, we are breaking down into multiple requests (250 fields/request) to avoid payload too large.

Checklist

Delete any items that are not applicable to this PR.

Risk Matrix

Delete this section if it is not applicable to this PR.

Before closing this PR, invite QA, stakeholders, and other developers to identify risks that should be tested prior to the change/feature release.

When forming the risk matrix, consider some of the following examples and how they may potentially impact the change:

Risk Probability Severity Mitigation/Notes
Multiple Spaces—unexpected behavior in non-default Kibana Space. Low High Integration tests will verify that all features are still supported in non-default Kibana Space and when user switches between spaces.
Multiple nodes—Elasticsearch polling might have race conditions when multiple Kibana nodes are polling for the same tasks. High Low Tasks are idempotent, so executing them multiple times will not result in logical error, but will degrade performance. To test for this case we add plenty of unit tests around this logic and document manual testing procedure.
Code should gracefully handle cases when feature X or plugin Y are disabled. Medium High Unit tests will verify that any feature flag or plugin combination still results in our service operational.
See more potential risk examples

For maintainers

@qn895 qn895 self-assigned this Jul 9, 2024
@qn895 qn895 added Feature:ES|QL ES|QL related features in Kibana Team:ESQL ES|QL related features in Kibana v8.16.0 labels Jul 9, 2024
@qn895
Copy link
Member Author

qn895 commented Jul 10, 2024

/ci

@qn895
Copy link
Member Author

qn895 commented Jul 10, 2024

/ci

@qn895
Copy link
Member Author

qn895 commented Jul 10, 2024

/ci

@qn895
Copy link
Member Author

qn895 commented Jul 10, 2024

/ci

@qn895 qn895 marked this pull request as ready for review July 11, 2024 00:24
@qn895 qn895 requested review from a team as code owners July 11, 2024 00:24
@elasticmachine
Copy link
Contributor

Pinging @elastic/kibana-esql (Team:ESQL)

Copy link
Contributor

@stratoula stratoula left a comment

Choose a reason for hiding this comment

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

This is awesome 😍 I love it, can you take a look on my comment below? We might not be able to improve it but if you can confirm for me would be awesome!

Not sure if it is possible with Monaco:

Here if I dont open the popover it feels a bit weird that looks like String ECS..., I would expect at least a separator.

image

In cases without the description I like the fact that I see the type here

image

but opening the popover to see the type again is unnecessary.

I wonder if we can do something better here. Possibly not because monaco doesnt allow us but can you take a look just to confirm?

import type { FieldsMetadataPublicStart } from '@kbn/fields-metadata-plugin/public';

describe('getColumnsWithMetadata', () => {
it('should return columns as is if fieldsMetadata is not provided', async () => {
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
it('should return columns as is if fieldsMetadata is not provided', async () => {
it('should return columns if fieldsMetadata is not provided', async () => {

Copy link
Member Author

Choose a reason for hiding this comment

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

Updated here 22db292 (#187922)

expect(result).toEqual(columns);
});

it('should return columns as is if ECS version field is not present', async () => {
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
it('should return columns as is if ECS version field is not present', async () => {
it('should return columns if ECS version field is not present', async () => {

Copy link
Member Author

@qn895 qn895 Jul 12, 2024

Choose a reason for hiding this comment

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

Updated here 22db292 (#187922)

@@ -18,6 +18,9 @@ export interface ESQLVariable {
export interface ESQLRealField {
Copy link
Contributor

Choose a reason for hiding this comment

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

This name is funny 😄

@@ -430,7 +440,8 @@ export const TextBasedLanguagesEditor = memo(function TextBasedLanguagesEditor({
undefined,
abortController
).result;
return table?.columns.map((c) => ({ name: c.name, type: c.meta.type })) || [];
const columns = table?.columns.map((c) => ({ name: c.name, type: c.meta.type })) || [];
return await getColumnsWithMetadata(columns, fieldsMetadata);
Copy link
Contributor

Choose a reason for hiding this comment

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

Very smart you are doing this here, this way we are using the cache 👏

Comment on lines 41 to 53
const fields = await fieldsMetadataClient.find({
fieldNames: columns.map((c) => c.name),
});

if (fields.fields) {
return columns.map((c) => ({
...c,
// Metadata services gives description for
// 'ecs.version' but not 'ecs.version.keyword'
// but both should show description if available
metadata: fields.fields[removeKeywordSuffix(c.name)],
}));
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Great usage of the FieldsMetadata service @qn895 👏

Tip

A further optimization here is to reduce a lot the API response payload by only keeping the field attributes you need, which I think it only consists of description so far! You can achieve it by passing the attributes option, this will return only the essential attributes for this use case and reduce quite a lot the API response size:

const {fields} = await fieldsMetadataClient.find({
  fieldNames: columns.map((c) => c.name),
  attributes: ['description']
});

if (fields) {
  return columns.map((c) => ({
    ...c,
    // Metadata services gives description for
    // 'ecs.version' but not 'ecs.version.keyword'
    // but both should show description if available
    metadata: fields[removeKeywordSuffix(c.name)],
  }));
}

Copy link
Member Author

Choose a reason for hiding this comment

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

Updated here 2695236

const metadata = fields.fields[removeKeywordSuffix(c.name)];

// Need to convert metadata's type (e.g. keyword) to ES|QL type (e.g. string) to check if they are the same
if (!metadata || convertEcsFieldTypeToESQLType(metadata.type) !== c.type) return c;
Copy link
Contributor

Choose a reason for hiding this comment

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

We could also use esFieldTypeToKibanaFieldType(metadata.type) !== c.type

Copy link
Member Author

Choose a reason for hiding this comment

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

Perfection! Thanks for the hint. Updated here 567cfa9 (#187922)

@stratoula
Copy link
Contributor

/ci

@@ -60,4 +60,4 @@
.TextBasedLangEditor--expanded .monaco-editor, .TextBasedLangEditor--expanded .monaco-editor .margin, .TextBasedLangEditor--expanded .monaco-editor .overflow-guard {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

If you revert this exactly as it was, we won't need the design team review

Copy link
Contributor

@stratoula stratoula left a comment

Choose a reason for hiding this comment

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

This is awesome! LGTM! 👏

Copy link
Contributor

@ryankeairns ryankeairns left a comment

Choose a reason for hiding this comment

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

Looks great! Other feedback thus far seems to have tightened the UX up even further.

@elasticmachine
Copy link
Contributor

💛 Build succeeded, but was flaky

Failed CI Steps

Metrics [docs]

Module Count

Fewer modules leads to a faster build time

id before after diff
esql 58 64 +6
lens 1482 1483 +1
stackAlerts 150 151 +1
total +8

Public APIs missing comments

Total count of every public API that lacks a comment. Target amount is 0. Run node scripts/build_api_docs --plugin [yourplugin] --stats comments for more detailed information.

id before after diff
@kbn/esql-validation-autocomplete 182 183 +1

Async chunks

Total size of all lazy-loaded chunks that will be downloaded as the user navigates the app

id before after diff
esql 177.1KB 181.5KB +4.4KB

Page load bundle

Size of the bundles that are downloaded on every page load. Target size is below 100kb

id before after diff
esql 6.5KB 6.6KB +88.0B
kbnUiSharedDeps-srcJs 3.2MB 3.2MB +269.0B
total +357.0B
Unknown metric groups

API count

id before after diff
@kbn/esql-validation-autocomplete 193 194 +1

ESLint disabled line counts

id before after diff
@kbn/text-based-editor 5 7 +2

Total ESLint disabled count

id before after diff
@kbn/text-based-editor 5 7 +2

History

cc @qn895

@qn895 qn895 merged commit 0ac61b7 into elastic:main Jul 15, 2024
21 checks passed
@kibanamachine kibanamachine added the backport:skip This commit does not require backporting label Jul 15, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backport:skip This commit does not require backporting Feature:ES|QL ES|QL related features in Kibana release_note:enhancement Team:ESQL ES|QL related features in Kibana v8.16.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[ES|QL] Prioritize fields based on ecs information on the editor
9 participants