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

Make ScriptFieldMapper a parameterized mapper #59391

Conversation

javanna
Copy link
Member

@javanna javanna commented Jul 13, 2020

This PR is opened against the runtime fields feature branch.

Relates to #59332

@javanna javanna added the :Search/Search Search-related issues that do not fall into other categories label Jul 13, 2020
@javanna javanna requested review from nik9000 and romseygeek July 13, 2020 10:05
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 think we should look into making ScriptService available via the parser context which should clear up the SetOnce nastiness.

}
}

public static class TypeParser implements Mapper.TypeParser {

private final SetOnce<ScriptService> scriptService = new SetOnce<>();
// TODO this is quite ugly and it's static which makes it even worse
private static final SetOnce<ScriptService> SCRIPT_SERVICE = new SetOnce<>();

Copy link
Contributor

Choose a reason for hiding this comment

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

Is there no way of getting it via the ParserContext?

Copy link
Contributor

Choose a reason for hiding this comment

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

It looks as though we'd have to wire ScriptService into MapperService, but I think that's a reasonable thing to do

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 will look into it, thanks for the suggestion.

) {
super(simpleName, mappedFieldType, multiFields, copyTo);
// TODO is it ok that the object being built needs to read from the object that is building it? Shouldn't Builder#build return
// a complete object? Maybe all the parameters need to be passed through instead of the whole builder?
Copy link
Member Author

Choose a reason for hiding this comment

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

@romseygeek this is for you, does it make sense?

Copy link
Contributor

Choose a reason for hiding this comment

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

Given that the mapper constructor is protected here, I think it's OK? You can pull out individual parameters if you think it's clearer, I used this pattern on other mappers simply because otherwise you end up with 14 constructor parameters most of which are just boilerplate.

null
);
// TODO script and runtime_type can be updated: what happens to the currently running queries when they get updated?
// do all the shards get a consistent view?
Copy link
Member Author

Choose a reason for hiding this comment

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

@romseygeek do you have thoughts on this?

Copy link
Contributor

Choose a reason for hiding this comment

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

So currently QueryShardContext#fieldMapper() delegates field lookups back to the MapperService, which gets updated in-place, so if there's an update while a query is running then the script will get changed out and there may well be inconsistencies between phases, as well as between shards. We could make QueryShardContext take a FieldTypeLookup as a parameter which would at least remove the possibility of an update between phases?

Copy link
Member

Choose a reason for hiding this comment

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

We have this sort of problem now with any thing that can change. I guess scripts make this worse because they are "more mutable" than other stuff.

} else {
throw new IllegalArgumentException("runtime_type [" + runtimeType + "] not supported");
}
// TODO copy to and multi_fields... not sure what needs to be done.
return new ScriptFieldMapper(name, mappedFieldType, multiFieldsBuilder.build(this, context), copyTo);
// TODO copy to and multi_fields should not be supported, parametrized field mapper needs to be adapted
Copy link
Member Author

Choose a reason for hiding this comment

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

@romseygeek and this one too. I think I would prefer making the changes upstream instead of adapting parameterized field mapper in the feature branch. Thoughts?

Copy link
Contributor

Choose a reason for hiding this comment

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

++, I can work 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.

thanks that would be great!

@javanna javanna marked this pull request as ready for review July 13, 2020 13:19
@elasticmachine
Copy link
Collaborator

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

@elasticmachine elasticmachine added the Team:Search Meta label for search team label Jul 13, 2020
@javanna
Copy link
Member Author

javanna commented Jul 13, 2020

This is now ready. There are two TODOs left to address which can be addressed later:

  1. rejecting multi fields and copy to on top of script fields
  2. thinking about script updates and their effect on running queries, and what we can do about that

assertEquals("Failed to parse mapping: script must be specified for script field [my_field]", exception.getMessage());
}

@AwaitsFix(bugUrl = "Nik: help! :)")
Copy link
Member Author

Choose a reason for hiding this comment

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

@nik9000 help!

null
);
// TODO script and runtime_type can be updated: what happens to the currently running queries when they get updated?
// do all the shards get a consistent view?
Copy link
Member

Choose a reason for hiding this comment

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

We have this sort of problem now with any thing that can change. I guess scripts make this worse because they are "more mutable" than other stuff.


private final SetOnce<ScriptService> scriptService = new SetOnce<>();
@SuppressWarnings("unchecked")
static Script parseScript(String name, Mapper.TypeParser.ParserContext parserContext, Object scriptObject) {
Copy link
Member

Choose a reason for hiding this comment

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

I swear I've seen this before somewhere else...

Copy link
Member Author

Choose a reason for hiding this comment

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

you may have, but we only accept painless and we don't parse stored scripts. I will look though, I assumed that we never parse from a map but watcher may do that actually.

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 found it, it was in update by query, I opened #59507 so that we can test and reuse that existing code

// TODO these get passed in sometimes and we don't need them
node.remove("doc_values");
node.remove("index");
ScriptFieldMapper.Builder builder = new ScriptFieldMapper.Builder(name, parserContext.queryShardContextSupplier());
Copy link
Member

Choose a reason for hiding this comment

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

I think queryShardContextSupplier exists for the percolator and it is a bit sneaky. It'll do but I'd feel more comfortable if we had the ScriptService directly.

super(simpleName, mappedFieldType, multiFields, copyTo);
this.runtimeType = runtimeType;
this.script = script;
this.queryShardContextSupplier = queryShardContextSupplier;
Copy link
Member

Choose a reason for hiding this comment

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

I worry about keeping the queryShardContextSupplier around because it is sneaky. Could getMergeBuilder get the parse context or something like that?

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 agree. I personally prefer the hack that we had before (SetOnce in the type parser, set from the plugin class). Otherwise I can get the query shard context from the parser context and pass in only the script service, hopefully it is available.

}

@AwaitsFix(bugUrl = "Nik: help! :)")
public void testDefaultMapping() 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.

Is the idea to test that we can properly parse a simple version of the mapper? I don't really get the name of the method. I will try and hack on it locally and let you know what I find.

Copy link
Member Author

Choose a reason for hiding this comment

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

the name is from a copy/paste. I wanted to test that the mapper works indeed.

javanna added a commit to javanna/elasticsearch that referenced this pull request Jul 14, 2020
The update by query action parses a script from an object (map or string). We will need to do the same for runtime fields as they are parsed as part of mappings (elastic#59391).

This commit moves the existing parsing of a script from an object from RestUpdateByQueryAction to the Script class. It also adds tests and adjusts some error messages that are incorrect. Also, options were not parsed before and they are now. And unsupported fields are no longer silently ignored.
javanna added a commit to javanna/elasticsearch that referenced this pull request Jul 14, 2020
The update by query action parses a script from an object (map or string). We will need to do the same for runtime fields as they are parsed as part of mappings (elastic#59391).

This commit moves the existing parsing of a script from an object from RestUpdateByQueryAction to the Script class. It also adds tests and adjusts some error messages that are incorrect. Also, options were not parsed before and they are now. And unsupported fields are no longer silently ignored.
javanna added a commit that referenced this pull request Jul 14, 2020
The update by query action parses a script from an object (map or string). We will need to do the same for runtime fields as they are parsed as part of mappings (#59391).

This commit moves the existing parsing of a script from an object from RestUpdateByQueryAction to the Script class. It also adds tests and adjusts some error messages that are incorrect. Also, options were not parsed before and they are now. And unsupported fields are no longer silently ignored.
@javanna
Copy link
Member Author

javanna commented Jul 14, 2020

I addressed another TODO around the type to be returned and a couple of issues around field caps, as well as added a test for field_caps. This should be ready. I'd like to discuss separately what we should do to clean up how get the reference to ScriptService.

Copy link
Member

@nik9000 nik9000 left a comment

Choose a reason for hiding this comment

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

LGTM

@javanna javanna merged commit 4eb18b2 into elastic:feature/runtime_fields Jul 14, 2020
javanna added a commit that referenced this pull request Jul 14, 2020
The update by query action parses a script from an object (map or string). We will need to do the same for runtime fields as they are parsed as part of mappings (#59391).

This commit moves the existing parsing of a script from an object from RestUpdateByQueryAction to the Script class. It also adds tests and adjusts some error messages that are incorrect. Also, options were not parsed before and they are now. And unsupported fields trigger now a deprecation warning.
@javanna javanna mentioned this pull request Jul 15, 2020
30 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
:Search/Search Search-related issues that do not fall into other categories Team:Search Meta label for search team
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants