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

Refactor how to determine if a field is metafield #57378

Merged

Conversation

mayya-sharipova
Copy link
Contributor

Before to determine if a field is meta-field, a static method of MapperService
isMetadataField was used. This method was using an outdated static list
of meta-fields.

This PR instead changes this method to the instance method that
is also aware of meta-fields in all registered plugins.

Related #38373, #41656
Closes #24422

@mayya-sharipova mayya-sharipova added >non-issue :Search/Search Search-related issues that do not fall into other categories v8.0.0 v7.9.0 labels May 29, 2020
@elasticmachine
Copy link
Collaborator

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

Before to determine if a field is meta-field, a static method of MapperService
isMetadataField was used. This method was using an outdated static list
of meta-fields.

This PR instead changes this method to the instance method that
is also aware of meta-fields in all registered plugins.

Related elastic#38373, elastic#41656
Closes elastic#24422
Copy link
Member

@cbuescher cbuescher left a comment

Choose a reason for hiding this comment

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

Thanks @mayya-sharipova, I did a first pass and it looks great I think. Left a few questions/comments but nothing big I think. One general question I have around the goals of this PR wrt testing: in your description you write that

This PR instead changes this method to the instance method that
is also aware of meta-fields in all registered plugins.

Is there any way to test (unit or IT test) we really pick up meta-fields from other plugins this way? Or is this already covered, e.g. by yml test in the mapper-size plugin that would break if we wouldn't use the mapperRegistry but e.g. only the core built-in meta-fields?

if (fieldsVisitor == null) {
return new SearchHit(docId, null, null, null);

return new SearchHit(docId, null, docFields, metaFields);
Copy link
Member

Choose a reason for hiding this comment

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

I'd probably prefer it if we continue using null arguments and remove earlier declaration of maps (move it down to where they are needed?)

@@ -278,11 +251,17 @@ private SearchHit createNestedSearchHit(SearchContext context,
source = null;
}

Map<String, DocumentField> searchFields = null;
Map<String, DocumentField> docFields = emptyMap();
Copy link
Member

Choose a reason for hiding this comment

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

I'd prefer modifiable maps right here and remove L261/262 instead. Just for readability

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Indeed, readability will be improved with this suggestion. But I think it is more important not to create unnecessary HashMap object for every nested hit, that's why I set it to emptyMap(). I can also set it to null as it was before. What do you think?

if (hitField == null) {
hitField = new DocumentField(field, new ArrayList<>(2));
hit.setField(field, hitField);
// docValues field is put under "fields" even if they are meta-data fields
Copy link
Member

Choose a reason for hiding this comment

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

I was under the impression docValues are put under "documentFields", not meta? Am I missing sth here? Maybe rephrase?

String metaField = randomValueOtherThanMany(field -> field.equals(TypeFieldMapper.NAME)
|| field.equals(IndexFieldMapper.NAME) || field.equals(IdFieldMapper.NAME),
() -> randomFrom(MapperService.getAllMetaFields()));
|| field.equals(IndexFieldMapper.NAME) || field.equals(IdFieldMapper.NAME)
Copy link
Member

Choose a reason for hiding this comment

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

Do you know why we exclude these random field types here? I don't remember atm, if you do (bc. you added some cases) maybe a comment would help my future me understanding this better.

if (IndicesModule.getBuiltInMetadataFields().contains(fieldName)) {
return true;
}
// adding _size field as meta-field for bwc
Copy link
Member

Choose a reason for hiding this comment

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

Since this sticks out as odd, maybe extend the comment by briefly explaining the cases where we need this. As far as I understand this should only be the case when a pre-7.3 node uses the size mapper plugin and sends these fields jumbled with the other document fields, right?

@mayya-sharipova
Copy link
Contributor Author

@cbuescher Thank you for the review. I have tried to address your comments in 3a56fd2. Please continue to review when you have time.

Is there any way to test (unit or IT test) we really pick up meta-fields from other plugins this way?

I have added a test RankFeatureMetaFieldMapperTests:: testDocumentParsingFailsOnMetaField that uses MapperExtrasPlugin, where document parsing fails on a meta-field _feature from this plugin.

@mayya-sharipova
Copy link
Contributor Author

@elasticmachine run elasticsearch-ci/bwc

Copy link
Member

@cbuescher cbuescher left a comment

Choose a reason for hiding this comment

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

Hi @mayya-sharipova, thanks for the update and adressing the previous review comments. I just have one tiny ask around comments of the new tests, but no need for another round.

@@ -55,4 +57,14 @@ public void testBasics() throws Exception {
assertEquals(mapping, mapper.mappingSource().toString());
assertNotNull(mapper.metadataMapper(RankFeatureMetaFieldMapper.class));
}

public void testDocumentParsingFailsOnMetaField() throws Exception {
Copy link
Member

Choose a reason for hiding this comment

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

Great way to test!
nit: could you add a very brief comment explaining why this proves the metadata field from the plugin was correctly registered? Makes it easier to later track why tests are there and what they check.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@cbuescher Thank you for the review.
The last comment addressed in ac6a4bc

@mayya-sharipova mayya-sharipova merged commit b68bd78 into elastic:master Jun 5, 2020
mayya-sharipova added a commit to mayya-sharipova/elasticsearch that referenced this pull request Jun 5, 2020
Before to determine if a field is meta-field, a static method of MapperService
isMetadataField was used. This method was using an outdated static list
of meta-fields.

This PR instead changes this method to the instance method that
is also aware of meta-fields in all registered plugins.

Related elastic#38373, elastic#41656
Closes elastic#24422
mayya-sharipova added a commit that referenced this pull request Jun 8, 2020
Before to determine if a field is meta-field, a static method of MapperService
isMetadataField was used. This method was using an outdated static list
of meta-fields.

This PR instead changes this method to the instance method that
is also aware of meta-fields in all registered plugins.

Related #38373, #41656
Closes #24422
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
>non-issue :Search/Search Search-related issues that do not fall into other categories Team:Search Meta label for search team v7.9.0 v8.0.0-alpha1
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Not all meta fields in _source print a nice error
4 participants