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

RuntimeField to expose more than one MappedFieldType #73900

Merged

Conversation

javanna
Copy link
Member

@javanna javanna commented Jun 8, 2021

Up until now, there was a 1:1 relationship between a RuntimeField and a MappedFieldType. Actually, the two were only recently split to support emitting multiple fields from a single runtime script. The next step is to change the signature of asMappedFieldType to make it return multiple sub-fields. The leaf fields that are supported to-date will return a collection with a single item, but the upcoming runtime "object" field will return as many subfields as are listed in its definition.

Together with this, we are introducing two consistency checks:

  • sub-fields exposed by a RuntimeField either have its same name, or belong to its namespace (e.g. object.subfield)
  • there can't be two mapped field types with the same name as part of the same runtime section, overrides happen defining the same field in two different sections (index mappings and search request)

Up until now, there was a 1:1 relationship between a RuntimeField and a MappedFieldType. Actually, the two were only recently split to support emitting multiple fields from a single runtime script. The next step is to change the signature of asMappedFieldType to make it return multiple sub-fields. The leaf fields that are supported to-date will return a collection with a single item, but the upcoming runtime "object" field will return as many subfields as are listed in its definition.

Together with this, we are introducing two consistency checks:
- sub-fields exposed by a RuntimeField either have its same name, or belong to its namespace (e.g. object.subfield)
- there can't be two mapped field types with the same name as part of the same runtime section, overrides happen defining the same field in two different sections (index mappings and search request)
@javanna javanna added :Search Foundations/Mapping Index mappings, including merging and defining field types >refactoring v8.0.0 v7.14.0 labels Jun 8, 2021
@javanna javanna requested review from romseygeek and jtibshirani June 8, 2021 13:29
@elasticmachine elasticmachine added the Team:Search Meta label for search team label Jun 8, 2021
@elasticmachine
Copy link
Collaborator

Pinging @elastic/es-search (Team:Search)

Copy link
Contributor

@romseygeek romseygeek left a comment

Choose a reason for hiding this comment

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

LGTM - I left a question about subfield naming though which I think we need to address before committing.

RuntimeField runtimeField = context.root().getRuntimeField(fieldPath);
if (runtimeField != null) {
return new NoOpFieldMapper(subfields[subfields.length - 1], runtimeField.asMappedFieldType().name());
MappedFieldType fieldType = context.mappingLookup().getFieldType(fieldPath);
Copy link
Contributor

Choose a reason for hiding this comment

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

Will this work with flattened fields? I guess they should already be picked up by the parent.

Copy link
Member Author

Choose a reason for hiding this comment

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

I think that flattened have a mapper that would be found above?

Copy link
Contributor

Choose a reason for hiding this comment

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

I also think that flattened fields will be found earlier. Would you be up for adding a test for this, as it seems quite subtle?

Copy link
Member Author

Choose a reason for hiding this comment

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

I opened #74112

Copy link
Contributor

Choose a reason for hiding this comment

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

Thanks for the extra test !

.collect(Collectors.toList());
if (names.isEmpty() == false) {
throw new IllegalArgumentException("Found sub-fields with name not belonging to the parent field they are part of "
+ names);
Copy link
Contributor

Choose a reason for hiding this comment

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

This is interesting, are we sure that we want to enforce this? We've discussed in the past wanting to have subfields that are aliased out to the root so that they don't appear in their parent object's namespace. If we do enforce this then that's another reason to allow runtime aliases to refer to other runtime fields.

Copy link
Member Author

Choose a reason for hiding this comment

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

I was assuming that we do want to enforce this, otherwise object "foo" can emit sub-fields that don't belong to its namespace. We were trying to apply a similar assertion with the dynamic field type approach but it turned out not to be feasible due to flattened and aliases, I think.

In reality, this will not be possible if we look at how you define sub-fields (yet I think it's good to check to prevent mistakes), because the full name is generated by concatenating the name of the parent and the name of the sub-field:

"log" : {
    "type" : "I don't have a name yet"
    "script" : "...."
    "fields" : {
        "client_ip" : {
            "type" : "ip"
        }
    }
}

Maybe I should make it an illegal state instead of a user error...

While it is possible to have users define the full path in the sub-fields, that would make the "object" name almost useless and would feel weird. Your conclusion about aliases makes sense to me, although it is very easy to make an alias runtime field with a super small script?

Copy link
Member Author

Choose a reason for hiding this comment

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

I made this an IllegalStateException

Copy link
Contributor

Choose a reason for hiding this comment

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

Using IllegalStateException or an assertion here makes sense to me, as it'd indicate a bug in our code (or plugin authors' code). Not relevant to this PR, but I noticed we don't assert this for FieldMapper#iterator... maybe we should.

Copy link
Contributor

@romseygeek romseygeek left a comment

Choose a reason for hiding this comment

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

Thanks @javanna

@javanna javanna merged commit 7c641ec into elastic:master Jun 8, 2021
javanna added a commit to javanna/elasticsearch that referenced this pull request Jun 8, 2021
Up until now, there was a 1:1 relationship between a RuntimeField and a MappedFieldType. Actually, the two were only recently split to support emitting multiple fields from a single runtime script. The next step is to change the signature of asMappedFieldType to make it return multiple sub-fields. The leaf fields that are supported to-date will return a collection with a single item, but the upcoming runtime "object" field will return as many subfields as are listed in its definition.

Together with this, we are introducing two consistency checks:
- sub-fields exposed by a RuntimeField either have its same name, or belong to its namespace (e.g. object.subfield)
- there can't be two mapped field types with the same name as part of the same runtime section, overrides happen defining the same field in two different sections (index mappings and search request)
javanna added a commit that referenced this pull request Jun 8, 2021
Up until now, there was a 1:1 relationship between a RuntimeField and a MappedFieldType. Actually, the two were only recently split to support emitting multiple fields from a single runtime script. The next step is to change the signature of asMappedFieldType to make it return multiple sub-fields. The leaf fields that are supported to-date will return a collection with a single item, but the upcoming runtime "object" field will return as many subfields as are listed in its definition.

Together with this, we are introducing two consistency checks:
- sub-fields exposed by a RuntimeField either have its same name, or belong to its namespace (e.g. object.subfield)
- there can't be two mapped field types with the same name as part of the same runtime section, overrides happen defining the same field in two different sections (index mappings and search request)
RuntimeField runtimeField = context.root().getRuntimeField(fieldPath);
if (runtimeField != null) {
return new NoOpFieldMapper(subfields[subfields.length - 1], runtimeField.asMappedFieldType().name());
MappedFieldType fieldType = context.mappingLookup().getFieldType(fieldPath);
Copy link
Contributor

Choose a reason for hiding this comment

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

I also think that flattened fields will be found earlier. Would you be up for adding a test for this, as it seems quite subtle?

.collect(Collectors.toList());
if (names.isEmpty() == false) {
throw new IllegalArgumentException("Found sub-fields with name not belonging to the parent field they are part of "
+ names);
Copy link
Contributor

Choose a reason for hiding this comment

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

Using IllegalStateException or an assertion here makes sense to me, as it'd indicate a bug in our code (or plugin authors' code). Not relevant to this PR, but I noticed we don't assert this for FieldMapper#iterator... maybe we should.

@jtibshirani
Copy link
Contributor

Sorry for the late review, I had it open for a long time without refreshing the page!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
>refactoring :Search Foundations/Mapping Index mappings, including merging and defining field types Team:Search Meta label for search team v7.14.0 v8.0.0-alpha1
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants