Skip to content

Conversation

@javanna
Copy link
Member

@javanna javanna commented Nov 3, 2020

ValueFetcher needs only one method from MapperService: sourcePaths. The signature of MappedFieldType#valueFetcher requires MapperService as an argument which is unfortunate as that is one of the reasons why FetchContext exposes the whole MapperService.

This can be easily removed by having a specific lightweight object to carry around instead of the MapperService, that exposes only the needed method.

This change is marked breaking-java because it changes the signature of the MappedFieldType#valueFetcher method to take QueryShardContext as argument instead of MapperService. MapperPlugins that plug in a custom field type implementation will have to adapt their code to make it compile with Elasticsearch 7.11 and following versions.

@javanna javanna added :Search Foundations/Mapping Index mappings, including merging and defining field types >refactoring v8.0.0 v7.11.0 labels Nov 3, 2020
@javanna javanna requested review from nik9000 and romseygeek November 3, 2020 12:24
@elasticmachine
Copy link
Collaborator

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

@elasticmachine elasticmachine added the Team:Search Meta label for search team label Nov 3, 2020
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, very nice.

@javanna javanna requested a review from jtibshirani November 3, 2020 12:33
Copy link
Contributor

@jimczi jimczi left a comment

Choose a reason for hiding this comment

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

I left one comment

Copy link
Contributor

Choose a reason for hiding this comment

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

Why not using QueryShardContext ? We could also remove the SearchLookup argument.

Copy link
Member

Choose a reason for hiding this comment

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

Why not using QueryShardContext ? We could also remove the SearchLookup argument.

I'd prefer not to use QueryShardContext everywhere. It really is "too big" as it is.

For what it is worth, we could totally add SearchLookup to ValueFetcher.Context if we wanted.

But I've made three attempts at this change so far and we didn't like them so I'm kind of done having opinions here. Do whatever makes folks happy.

Copy link
Member Author

Choose a reason for hiding this comment

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

QueryShardContext is a huge object that I don't think we want to spread around more than it already is. While we remove the dependency from MapperService, I think that we should try and be careful with encapsulation and who gets access to what. sourcePath is currently not exposed anywhere other than MapperService, and we will have to find a way to expose it so we can progress with removing direct MapperService usages, but we want to be careful with adding new methods to all of the existing contexts, that already have many methods.

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 updated and added QueryShardContext as an argument. I am not sure about SearchLookup because it needs to retrieved specifically through QueryShardContext#newFetchLookup and reused. Looks like we should improve this as its confusing that you can get the lookup also from the context, though it would be the wrong one. I will leave this for another time though.

Copy link
Contributor

Choose a reason for hiding this comment

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

+1 to solve this as a follow up.

Copy link
Member

Choose a reason for hiding this comment

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

I'm not sure that this is better than my last attempt. I think it's up to @jtibshirani to make the call on this one.

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 the difference is subtle, but I believe this should address the concerns around tracking usages. At the same time we are introducing a lightweight abstraction that clearly encapsulates what is needed to fetch values, which is much harder to read when functions are carried around. I would love for Julie to have a look and let us know what she thinks though.

@jimczi
Copy link
Contributor

jimczi commented Nov 3, 2020

I think it's important to be consistent here. IMO the QueryShardContext is the lightweight object that we use when parsing/building/fetching in the query or the fetch phase so it's logic to expose it entirely. Look at the existing query methods in MappedFieldType, they already expose the QueryShardContext. We could argue that they don't need the entire context but that would make the API more complex to use.
My point here is that the QSC is the right abstraction to expose for consistency. We can ensure that nothing unsafe leaks in a central point.

The signature of MappedFieldType#valueFetcher requires MapperService as an argument which is unfortunate as that is one of the reasons why FetchContext exposes the whole MapperService.

Such use of MapperService can be replaced with exposing the QueryShardContext which encapsulates the MapperService.
@javanna javanna force-pushed the refactoring/value_fetcher_mapper_service branch from 362aceb to e2462f5 Compare November 3, 2020 16:29

@Override
public ValueFetcher valueFetcher(MapperService mapperService, SearchLookup searchLookup, String format) {
public ValueFetcher valueFetcher(QueryShardContext context, SearchLookup searchLookup, String format) {
Copy link
Contributor

Choose a reason for hiding this comment

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

If we're passing QueryShardContext I think that means we can avoid passing SearchLookup here?

Copy link
Member Author

Choose a reason for hiding this comment

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

see my comment above, I don't think so, because we need to pass through the fetch lookup that is created in FetchContext?

@javanna javanna requested a review from romseygeek November 4, 2020 09:57
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.

One nit, but LGTM otherwise.

return mapperService.isMetadataField(field);
}

public Set<String> sourcePath(String fullName) {
Copy link
Contributor

Choose a reason for hiding this comment

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

One nit: maybe this should be sourcePaths, given that it can return more than one?

Copy link
Member Author

Choose a reason for hiding this comment

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

yes, in my iterations I did both, I went for singular for consistency with the name of the method in MapperService. I don't know what is more important between using the same name or using the correct name here. Maybe we should rename both as a followup?

Copy link
Contributor

Choose a reason for hiding this comment

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

+1 for a followup

@javanna javanna merged commit 344ad33 into elastic:master Nov 4, 2020
javanna added a commit that referenced this pull request Nov 4, 2020
javanna added a commit to javanna/elasticsearch that referenced this pull request Nov 4, 2020
The signature of MappedFieldType#valueFetcher requires MapperService as an argument which is unfortunate as that is one of the reasons why FetchContext exposes the whole MapperService.

Such use of MapperService can be replaced with exposing the QueryShardContext which encapsulates the MapperService.
javanna added a commit that referenced this pull request Nov 5, 2020
The signature of MappedFieldType#valueFetcher requires MapperService as an argument which is unfortunate as that is one of the reasons why FetchContext exposes the whole MapperService.

Such use of MapperService can be replaced with exposing the QueryShardContext which encapsulates the MapperService.
csoulios added a commit to csoulios/elasticsearch that referenced this pull request Nov 5, 2020
Copy link
Contributor

@jtibshirani jtibshirani left a comment

Choose a reason for hiding this comment

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

Sorry for the slow review, I like the approach taken in the PR to pass in QueryShardContext. +1 to think about a follow-up refactor where we avoid passing around QueryShardContext and SearchLookup separately.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

>breaking-java >refactoring :Search Foundations/Mapping Index mappings, including merging and defining field types Team:Search Meta label for search team v7.11.0 v8.0.0-alpha1

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants