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

Share data between DocValuesField and ScriptDocValues #79587

Merged
merged 9 commits into from
Oct 25, 2021

Conversation

jdconrad
Copy link
Contributor

This change makes it so there is only one path to retrieve values for scripting through the newly introduced fields API. To support backwards compatibility of ScriptDocValues, DocValuesField will return ScriptDocValues for continued doc access where the values are shared, so there is no double loading of field data. For now, for unsupported DocValuesFields we have a DelegateDocValuesField that returns the ScriptDocValues for long, double, String, etc.

@jdconrad jdconrad added :Core/Infra/Scripting Scripting abstractions, Painless, and Mustache >refactoring v8.0.0 labels Oct 20, 2021
@elasticmachine elasticmachine added the Team:Core/Infra Meta label for core/infra team label Oct 20, 2021
@elasticmachine
Copy link
Collaborator

Pinging @elastic/es-core-infra (Team:Core/Infra)

@jdconrad jdconrad requested a review from stu-elastic October 20, 2021 22:30

import java.io.IOException;
import java.util.List;

Copy link
Contributor

Choose a reason for hiding this comment

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

Minimal javadoc, please

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

}

class org.elasticsearch.script.field.DelegateDocValuesField @dynamic_type {
def getValue(def)
Copy link
Contributor

@stu-elastic stu-elastic Oct 25, 2021

Choose a reason for hiding this comment

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

Why did we need to add this now? I would have figured we needed this when adding unsigned long?

Copy link
Contributor Author

@jdconrad jdconrad Oct 25, 2021

Choose a reason for hiding this comment

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

Delegate field isn't used for unsigned long; it's only used for types that we still provide through only doc. The base Field class doesn't have a getValue or getValues. I added these methods here so a user attempting to access a field type we don't have a new mapped type for, will know they have to use doc.

Edit:
We removed getValue and getValues from the base Field class so that sub classes can return primitives directly with getValue. Dynamic languages can provide this automatically, and non-dynamic languages would require a cast to get the appropriate value type either way, so it didn't make sense to keep them.

import java.util.List;

/**
* A default field to provide {@code ScriptDocValues} for fields
Copy link
Contributor

Choose a reason for hiding this comment

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

A default Field?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed.

@@ -121,7 +121,7 @@ public void testCannotReferToRuntimeFields() throws IOException {

Exception e = expectThrows(MapperParsingException.class, () -> mapper.parse(source(b -> {})));
assertEquals("Error executing script on field [index-field]", e.getMessage());
assertEquals("No field found for [runtime-field] in mapping", e.getCause().getMessage());
assertEquals("no field found for [runtime-field] in mapping", e.getCause().getMessage());
Copy link
Contributor

Choose a reason for hiding this comment

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

Why the change here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed.

@@ -589,7 +591,7 @@ public ScoreMode scoreMode() {

@Override
public LeafCollector getLeafCollector(LeafReaderContext context) {
ScriptDocValues<?> scriptValues = indexFieldData.load(context).getScriptValues();
ScriptDocValues<?> scriptValues = indexFieldData.load(context).getScriptField("test").getScriptDocValues();
Copy link
Contributor

Choose a reason for hiding this comment

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

Why here rather than on line 605 and 607?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Moved.

@jdconrad
Copy link
Contributor Author

@stu-elastic Thanks for the review comments. I've addressed them, so this should be ready for re-review.

@@ -52,7 +51,7 @@ public DocValuesField getScriptField(String fieldName) {
final MappedFieldType fieldType = fieldTypeLookup.apply(fieldName);

if (fieldType == null) {
throw new IllegalArgumentException("no field found for [" + fieldName + "] in mapping");
throw new IllegalArgumentException("No field found for [" + fieldName + "] in mapping");
Copy link
Contributor

Choose a reason for hiding this comment

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

Why the change here?

Copy link
Contributor Author

@jdconrad jdconrad Oct 25, 2021

Choose a reason for hiding this comment

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

To match the error message that was previously there. I must have changed it when I was moving this from ScriptDocValues to Field.

Edit:
This is why the test had changed.

Copy link
Contributor

@stu-elastic stu-elastic left a comment

Choose a reason for hiding this comment

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

Nice work, this will make it cheap to gradually add fields api to existing scripts.

@jdconrad
Copy link
Contributor Author

@stu-elastic Thanks again! Will commit as soon as CI passes.

@jdconrad jdconrad merged commit afe1026 into elastic:master Oct 25, 2021
lockewritesdocs pushed a commit to lockewritesdocs/elasticsearch that referenced this pull request Oct 28, 2021
This change makes it so there is only one path to retrieve values for scripting through the newly 
introduced fields API. To support backwards compatibility of ScriptDocValues, DocValuesField will 
return ScriptDocValues for continued doc access where the values are shared, so there is no 
double loading of field data. For now, for unsupported DocValuesFields we have a 
DelegateDocValuesField that returns the ScriptDocValues for long, double, String, etc.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
:Core/Infra/Scripting Scripting abstractions, Painless, and Mustache >refactoring Team:Core/Infra Meta label for core/infra team v8.0.0-beta1
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants