Make ScriptFieldMapper a parameterized mapper#59391
Make ScriptFieldMapper a parameterized mapper#59391javanna merged 9 commits intoelastic:feature/runtime_fieldsfrom
Conversation
romseygeek
left a comment
There was a problem hiding this comment.
LGTM, I think we should look into making ScriptService available via the parser context which should clear up the SetOnce nastiness.
...ime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/mapper/ScriptFieldMapper.java
Outdated
Show resolved
Hide resolved
| 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<>(); | ||
|
|
There was a problem hiding this comment.
Is there no way of getting it via the ParserContext?
There was a problem hiding this comment.
It looks as though we'd have to wire ScriptService into MapperService, but I think that's a reasonable thing to do
There was a problem hiding this comment.
I will look into it, thanks for the suggestion.
...ime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/mapper/ScriptFieldMapper.java
Outdated
Show resolved
Hide resolved
| ) { | ||
| 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? |
There was a problem hiding this comment.
@romseygeek this is for you, does it make sense?
There was a problem hiding this comment.
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? |
There was a problem hiding this comment.
@romseygeek do you have thoughts on this?
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
| } | ||
| // 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 |
There was a problem hiding this comment.
@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?
There was a problem hiding this comment.
++, I can work on this one.
There was a problem hiding this comment.
thanks that would be great!
|
Pinging @elastic/es-search (:Search/Search) |
|
This is now ready. There are two TODOs left to address which can be addressed later:
|
| assertEquals("Failed to parse mapping: script must be specified for script field [my_field]", exception.getMessage()); | ||
| } | ||
|
|
||
| @AwaitsFix(bugUrl = "Nik: 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? |
There was a problem hiding this comment.
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) { |
There was a problem hiding this comment.
I swear I've seen this before somewhere else...
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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()); |
There was a problem hiding this comment.
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; |
There was a problem hiding this comment.
I worry about keeping the queryShardContextSupplier around because it is sneaky. Could getMergeBuilder get the parse context or something like that?
There was a problem hiding this comment.
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.
...ime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/mapper/ScriptFieldMapper.java
Outdated
Show resolved
Hide resolved
| } | ||
|
|
||
| @AwaitsFix(bugUrl = "Nik: help! :)") | ||
| public void testDefaultMapping() throws Exception { |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
the name is from a copy/paste. I wanted to test that the mapper works indeed.
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.
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.
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.
|
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. |
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.
This PR is opened against the runtime fields feature branch.
Relates to #59332