diff --git a/modules/lang-painless/src/main/resources/org/elasticsearch/painless/org.elasticsearch.script.fields.txt b/modules/lang-painless/src/main/resources/org/elasticsearch/painless/org.elasticsearch.script.fields.txt index af330de477216..cf8f1ff2560b5 100644 --- a/modules/lang-painless/src/main/resources/org/elasticsearch/painless/org.elasticsearch.script.fields.txt +++ b/modules/lang-painless/src/main/resources/org/elasticsearch/painless/org.elasticsearch.script.fields.txt @@ -16,5 +16,10 @@ class org.elasticsearch.script.field.Field @dynamic_type { } class org.elasticsearch.script.DocBasedScript { - org.elasticsearch.script.field.Field field(String) + org.elasticsearch.script.field.Field field(String) +} + +class org.elasticsearch.script.field.DelegateDocValuesField @dynamic_type { + def getValue(def) + List getValues() } diff --git a/modules/lang-painless/src/yamlRestTest/resources/rest-api-spec/test/painless/20_scriptfield.yml b/modules/lang-painless/src/yamlRestTest/resources/rest-api-spec/test/painless/20_scriptfield.yml index 3a3e5608e02bf..7c3a9d975efeb 100644 --- a/modules/lang-painless/src/yamlRestTest/resources/rest-api-spec/test/painless/20_scriptfield.yml +++ b/modules/lang-painless/src/yamlRestTest/resources/rest-api-spec/test/painless/20_scriptfield.yml @@ -154,3 +154,32 @@ setup: - match: { error.failed_shards.0.reason.caused_by.reason: "no paths escape from while loop" } - match: { error.failed_shards.0.reason.type: "script_exception" } - match: { error.failed_shards.0.reason.reason: "compile error" } + +--- +"Scripted Field with error accessing an unsupported field via the script fields api": + - do: + catch: bad_request + search: + rest_total_hits_as_int: true + body: + script_fields: + bar: + script: + source: "field('foo').getValue('')" + + - match: { error.failed_shards.0.reason.caused_by.type: "unsupported_operation_exception" } + - match: { error.failed_shards.0.reason.caused_by.reason: "field [foo] is not supported through the fields api, use [doc] instead"} + + - do: + catch: bad_request + search: + rest_total_hits_as_int: true + body: + script_fields: + bar: + script: + source: "field('foo').getValues()" + + - match: { error.failed_shards.0.reason.caused_by.type: "unsupported_operation_exception" } + - match: { error.failed_shards.0.reason.caused_by.reason: "field [foo] is not supported through the fields api, use [doc] instead" } + diff --git a/modules/mapper-extras/src/main/java/org/elasticsearch/index/mapper/extras/ScaledFloatFieldMapper.java b/modules/mapper-extras/src/main/java/org/elasticsearch/index/mapper/extras/ScaledFloatFieldMapper.java index ff585b416b72c..dc7575728fa86 100644 --- a/modules/mapper-extras/src/main/java/org/elasticsearch/index/mapper/extras/ScaledFloatFieldMapper.java +++ b/modules/mapper-extras/src/main/java/org/elasticsearch/index/mapper/extras/ScaledFloatFieldMapper.java @@ -18,6 +18,8 @@ import org.elasticsearch.common.Explicit; import org.elasticsearch.common.settings.Setting; import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.script.field.DelegateDocValuesField; +import org.elasticsearch.script.field.DocValuesField; import org.elasticsearch.xcontent.XContentParser; import org.elasticsearch.xcontent.XContentParser.Token; import org.elasticsearch.common.xcontent.support.XContentMapValues; @@ -505,8 +507,8 @@ private static class ScaledFloatLeafFieldData implements LeafNumericFieldData { } @Override - public ScriptDocValues.Doubles getScriptValues() { - return new ScriptDocValues.Doubles(getDoubleValues()); + public DocValuesField getScriptField(String name) { + return new DelegateDocValuesField(new ScriptDocValues.Doubles(getDoubleValues()), name); } @Override diff --git a/server/src/main/java/org/elasticsearch/index/fielddata/IpScriptFieldData.java b/server/src/main/java/org/elasticsearch/index/fielddata/IpScriptFieldData.java index 7d343e44ffb81..efb9468aa631f 100644 --- a/server/src/main/java/org/elasticsearch/index/fielddata/IpScriptFieldData.java +++ b/server/src/main/java/org/elasticsearch/index/fielddata/IpScriptFieldData.java @@ -17,6 +17,8 @@ import org.elasticsearch.index.mapper.IpFieldMapper; import org.elasticsearch.indices.breaker.CircuitBreakerService; import org.elasticsearch.script.IpFieldScript; +import org.elasticsearch.script.field.DelegateDocValuesField; +import org.elasticsearch.script.field.DocValuesField; import org.elasticsearch.search.aggregations.support.CoreValuesSourceType; import org.elasticsearch.search.aggregations.support.ValuesSourceType; @@ -50,8 +52,8 @@ public BinaryScriptLeafFieldData loadDirect(LeafReaderContext context) throws Ex IpFieldScript script = leafFactory.newInstance(context); return new BinaryScriptLeafFieldData() { @Override - public ScriptDocValues getScriptValues() { - return new IpScriptDocValues(getBytesValues()); + public DocValuesField getScriptField(String name) { + return new DelegateDocValuesField(new IpScriptDocValues(getBytesValues()), name); } @Override diff --git a/server/src/main/java/org/elasticsearch/index/fielddata/LeafFieldData.java b/server/src/main/java/org/elasticsearch/index/fielddata/LeafFieldData.java index 6e3b0f8135918..85f938e3b9e1e 100644 --- a/server/src/main/java/org/elasticsearch/index/fielddata/LeafFieldData.java +++ b/server/src/main/java/org/elasticsearch/index/fielddata/LeafFieldData.java @@ -20,17 +20,10 @@ */ public interface LeafFieldData extends Accountable, Releasable { - /** - * Returns field values for use in scripting. - */ - ScriptDocValues getScriptValues(); - /** * Returns an {@code Field} for use in accessing field values in scripting. */ - default DocValuesField getScriptField(String name) { - throw new UnsupportedOperationException(); - } + DocValuesField getScriptField(String name); /** * Return a String representation of the values. diff --git a/server/src/main/java/org/elasticsearch/index/fielddata/StringScriptFieldData.java b/server/src/main/java/org/elasticsearch/index/fielddata/StringScriptFieldData.java index dfb480e0b21e0..31e1e81c22396 100644 --- a/server/src/main/java/org/elasticsearch/index/fielddata/StringScriptFieldData.java +++ b/server/src/main/java/org/elasticsearch/index/fielddata/StringScriptFieldData.java @@ -11,6 +11,8 @@ import org.apache.lucene.index.LeafReaderContext; import org.elasticsearch.indices.breaker.CircuitBreakerService; import org.elasticsearch.script.StringFieldScript; +import org.elasticsearch.script.field.DelegateDocValuesField; +import org.elasticsearch.script.field.DocValuesField; import org.elasticsearch.search.aggregations.support.CoreValuesSourceType; import org.elasticsearch.search.aggregations.support.ValuesSourceType; @@ -42,8 +44,8 @@ public BinaryScriptLeafFieldData loadDirect(LeafReaderContext context) throws Ex StringFieldScript script = leafFactory.newInstance(context); return new BinaryScriptLeafFieldData() { @Override - public ScriptDocValues getScriptValues() { - return new ScriptDocValues.Strings(getBytesValues()); + public DocValuesField getScriptField(String name) { + return new DelegateDocValuesField(new ScriptDocValues.Strings(getBytesValues()), name); } @Override diff --git a/server/src/main/java/org/elasticsearch/index/fielddata/plain/AbstractLeafGeoPointFieldData.java b/server/src/main/java/org/elasticsearch/index/fielddata/plain/AbstractLeafGeoPointFieldData.java index 0cc013cca59e1..00b7512127daf 100644 --- a/server/src/main/java/org/elasticsearch/index/fielddata/plain/AbstractLeafGeoPointFieldData.java +++ b/server/src/main/java/org/elasticsearch/index/fielddata/plain/AbstractLeafGeoPointFieldData.java @@ -13,6 +13,8 @@ import org.elasticsearch.index.fielddata.MultiGeoPointValues; import org.elasticsearch.index.fielddata.ScriptDocValues; import org.elasticsearch.index.fielddata.SortedBinaryDocValues; +import org.elasticsearch.script.field.DelegateDocValuesField; +import org.elasticsearch.script.field.DocValuesField; import java.util.Collection; import java.util.Collections; @@ -25,8 +27,8 @@ public final SortedBinaryDocValues getBytesValues() { } @Override - public final ScriptDocValues.GeoPoints getScriptValues() { - return new ScriptDocValues.GeoPoints(getGeoPointValues()); + public final DocValuesField getScriptField(String name) { + return new DelegateDocValuesField(new ScriptDocValues.GeoPoints(getGeoPointValues()), name); } public static LeafGeoPointFieldData empty(final int maxDoc) { diff --git a/server/src/main/java/org/elasticsearch/index/fielddata/plain/AbstractLeafOrdinalsFieldData.java b/server/src/main/java/org/elasticsearch/index/fielddata/plain/AbstractLeafOrdinalsFieldData.java index 5321c8f93a3cc..3dd5071a4fe28 100644 --- a/server/src/main/java/org/elasticsearch/index/fielddata/plain/AbstractLeafOrdinalsFieldData.java +++ b/server/src/main/java/org/elasticsearch/index/fielddata/plain/AbstractLeafOrdinalsFieldData.java @@ -15,6 +15,8 @@ import org.elasticsearch.index.fielddata.FieldData; import org.elasticsearch.index.fielddata.ScriptDocValues; import org.elasticsearch.index.fielddata.SortedBinaryDocValues; +import org.elasticsearch.script.field.DelegateDocValuesField; +import org.elasticsearch.script.field.DocValuesField; import java.util.Collection; import java.util.Collections; @@ -34,8 +36,8 @@ protected AbstractLeafOrdinalsFieldData(Function getScriptValues() { - return scriptFunction.apply(getOrdinalsValues()); + public final DocValuesField getScriptField(String name) { + return new DelegateDocValuesField(scriptFunction.apply(getOrdinalsValues()), name); } @Override diff --git a/server/src/main/java/org/elasticsearch/index/fielddata/plain/BinaryDVLeafFieldData.java b/server/src/main/java/org/elasticsearch/index/fielddata/plain/BinaryDVLeafFieldData.java index c65cdae47bc65..613d289f12f1a 100644 --- a/server/src/main/java/org/elasticsearch/index/fielddata/plain/BinaryDVLeafFieldData.java +++ b/server/src/main/java/org/elasticsearch/index/fielddata/plain/BinaryDVLeafFieldData.java @@ -12,11 +12,12 @@ import org.apache.lucene.index.DocValues; import org.apache.lucene.index.LeafReader; import org.apache.lucene.util.Accountable; -import org.elasticsearch.index.fielddata.LeafFieldData; import org.elasticsearch.index.fielddata.FieldData; +import org.elasticsearch.index.fielddata.LeafFieldData; import org.elasticsearch.index.fielddata.ScriptDocValues; -import org.elasticsearch.index.fielddata.ScriptDocValues.Strings; import org.elasticsearch.index.fielddata.SortedBinaryDocValues; +import org.elasticsearch.script.field.DelegateDocValuesField; +import org.elasticsearch.script.field.DocValuesField; import java.io.IOException; import java.util.Collection; @@ -44,8 +45,8 @@ public SortedBinaryDocValues getBytesValues() { } @Override - public Strings getScriptValues() { - return new ScriptDocValues.Strings(getBytesValues()); + public DocValuesField getScriptField(String name) { + return new DelegateDocValuesField(new ScriptDocValues.Strings(getBytesValues()), name); } @Override diff --git a/server/src/main/java/org/elasticsearch/index/fielddata/plain/BytesBinaryDVLeafFieldData.java b/server/src/main/java/org/elasticsearch/index/fielddata/plain/BytesBinaryDVLeafFieldData.java index 8a1cc0aecc3fb..778c4d3634b9e 100644 --- a/server/src/main/java/org/elasticsearch/index/fielddata/plain/BytesBinaryDVLeafFieldData.java +++ b/server/src/main/java/org/elasticsearch/index/fielddata/plain/BytesBinaryDVLeafFieldData.java @@ -9,8 +9,9 @@ package org.elasticsearch.index.fielddata.plain; import org.apache.lucene.index.BinaryDocValues; -import org.apache.lucene.util.BytesRef; import org.elasticsearch.index.fielddata.ScriptDocValues; +import org.elasticsearch.script.field.DelegateDocValuesField; +import org.elasticsearch.script.field.DocValuesField; final class BytesBinaryDVLeafFieldData extends AbstractBinaryDVLeafFieldData { @@ -19,8 +20,8 @@ final class BytesBinaryDVLeafFieldData extends AbstractBinaryDVLeafFieldData { } @Override - public ScriptDocValues getScriptValues() { - return new ScriptDocValues.BytesRefs(getBytesValues()); + public DocValuesField getScriptField(String name) { + return new DelegateDocValuesField(new ScriptDocValues.BytesRefs(getBytesValues()), name); } } diff --git a/server/src/main/java/org/elasticsearch/index/fielddata/plain/LeafDoubleFieldData.java b/server/src/main/java/org/elasticsearch/index/fielddata/plain/LeafDoubleFieldData.java index 85a3318e49134..5d769662d448b 100644 --- a/server/src/main/java/org/elasticsearch/index/fielddata/plain/LeafDoubleFieldData.java +++ b/server/src/main/java/org/elasticsearch/index/fielddata/plain/LeafDoubleFieldData.java @@ -16,6 +16,8 @@ import org.elasticsearch.index.fielddata.ScriptDocValues; import org.elasticsearch.index.fielddata.SortedBinaryDocValues; import org.elasticsearch.index.fielddata.SortedNumericDoubleValues; +import org.elasticsearch.script.field.DelegateDocValuesField; +import org.elasticsearch.script.field.DocValuesField; import org.elasticsearch.search.DocValueFormat; import java.io.IOException; @@ -40,8 +42,8 @@ public long ramBytesUsed() { } @Override - public final ScriptDocValues getScriptValues() { - return new ScriptDocValues.Doubles(getDoubleValues()); + public final DocValuesField getScriptField(String name) { + return new DelegateDocValuesField(new ScriptDocValues.Doubles(getDoubleValues()), name); } @Override diff --git a/server/src/main/java/org/elasticsearch/index/fielddata/plain/LeafLongFieldData.java b/server/src/main/java/org/elasticsearch/index/fielddata/plain/LeafLongFieldData.java index e90684c33c4c0..a602cefb58428 100644 --- a/server/src/main/java/org/elasticsearch/index/fielddata/plain/LeafLongFieldData.java +++ b/server/src/main/java/org/elasticsearch/index/fielddata/plain/LeafLongFieldData.java @@ -16,6 +16,8 @@ import org.elasticsearch.index.fielddata.ScriptDocValues; import org.elasticsearch.index.fielddata.SortedBinaryDocValues; import org.elasticsearch.index.fielddata.SortedNumericDoubleValues; +import org.elasticsearch.script.field.DelegateDocValuesField; +import org.elasticsearch.script.field.DocValuesField; import org.elasticsearch.search.DocValueFormat; import java.io.IOException; @@ -27,7 +29,7 @@ public abstract class LeafLongFieldData implements LeafNumericFieldData { private final long ramBytesUsed; /** - * Type of this field. Used to expose appropriate types in {@link #getScriptValues()}. + * Type of this field. Used to expose appropriate types in {@link #getScriptField(String)}}. */ private final NumericType numericType; @@ -42,18 +44,19 @@ public long ramBytesUsed() { } @Override - public final ScriptDocValues getScriptValues() { + public final DocValuesField getScriptField(String name) { switch (numericType) { // for now, dates and nanoseconds are treated the same, which also means, that the precision is only on millisecond level case DATE: - return new ScriptDocValues.Dates(getLongValues(), false); + return new DelegateDocValuesField(new ScriptDocValues.Dates(getLongValues(), false), name); case DATE_NANOSECONDS: assert this instanceof SortedNumericIndexFieldData.NanoSecondFieldData; - return new ScriptDocValues.Dates(((SortedNumericIndexFieldData.NanoSecondFieldData) this).getLongValuesAsNanos(), true); + return new DelegateDocValuesField( + new ScriptDocValues.Dates(((SortedNumericIndexFieldData.NanoSecondFieldData) this).getLongValuesAsNanos(), true), name); case BOOLEAN: - return new ScriptDocValues.Booleans(getLongValues()); + return new DelegateDocValuesField(new ScriptDocValues.Booleans(getLongValues()), name); default: - return new ScriptDocValues.Longs(getLongValues()); + return new DelegateDocValuesField(new ScriptDocValues.Longs(getLongValues()), name); } } diff --git a/server/src/main/java/org/elasticsearch/index/fielddata/plain/StringBinaryDVLeafFieldData.java b/server/src/main/java/org/elasticsearch/index/fielddata/plain/StringBinaryDVLeafFieldData.java index 8243307a8d3b3..19d13383347de 100644 --- a/server/src/main/java/org/elasticsearch/index/fielddata/plain/StringBinaryDVLeafFieldData.java +++ b/server/src/main/java/org/elasticsearch/index/fielddata/plain/StringBinaryDVLeafFieldData.java @@ -10,6 +10,8 @@ import org.apache.lucene.index.BinaryDocValues; import org.elasticsearch.index.fielddata.ScriptDocValues; +import org.elasticsearch.script.field.DelegateDocValuesField; +import org.elasticsearch.script.field.DocValuesField; final class StringBinaryDVLeafFieldData extends AbstractBinaryDVLeafFieldData { StringBinaryDVLeafFieldData(BinaryDocValues values) { @@ -17,7 +19,7 @@ final class StringBinaryDVLeafFieldData extends AbstractBinaryDVLeafFieldData { } @Override - public ScriptDocValues getScriptValues() { - return new ScriptDocValues.Strings(getBytesValues()); + public DocValuesField getScriptField(String name) { + return new DelegateDocValuesField(new ScriptDocValues.Strings(getBytesValues()), name); } } diff --git a/server/src/main/java/org/elasticsearch/index/mapper/IdFieldMapper.java b/server/src/main/java/org/elasticsearch/index/mapper/IdFieldMapper.java index d4902c9dafbf0..152bf0241ef3f 100644 --- a/server/src/main/java/org/elasticsearch/index/mapper/IdFieldMapper.java +++ b/server/src/main/java/org/elasticsearch/index/mapper/IdFieldMapper.java @@ -32,6 +32,8 @@ import org.elasticsearch.index.query.SearchExecutionContext; import org.elasticsearch.indices.IndicesService; import org.elasticsearch.indices.breaker.CircuitBreakerService; +import org.elasticsearch.script.field.DelegateDocValuesField; +import org.elasticsearch.script.field.DocValuesField; import org.elasticsearch.search.DocValueFormat; import org.elasticsearch.search.MultiValueMode; import org.elasticsearch.search.aggregations.support.CoreValuesSourceType; @@ -211,8 +213,8 @@ public long ramBytesUsed() { } @Override - public ScriptDocValues getScriptValues() { - return new ScriptDocValues.Strings(getBytesValues()); + public DocValuesField getScriptField(String name) { + return new DelegateDocValuesField(new ScriptDocValues.Strings(getBytesValues()), name); } @Override diff --git a/server/src/main/java/org/elasticsearch/index/mapper/flattened/KeyedFlattenedLeafFieldData.java b/server/src/main/java/org/elasticsearch/index/mapper/flattened/KeyedFlattenedLeafFieldData.java index 13c64f48a9859..16bc84653591b 100644 --- a/server/src/main/java/org/elasticsearch/index/mapper/flattened/KeyedFlattenedLeafFieldData.java +++ b/server/src/main/java/org/elasticsearch/index/mapper/flattened/KeyedFlattenedLeafFieldData.java @@ -13,11 +13,12 @@ import org.apache.lucene.util.Accountable; import org.apache.lucene.util.BytesRef; import org.elasticsearch.index.fielddata.AbstractSortedSetDocValues; -import org.elasticsearch.index.fielddata.LeafOrdinalsFieldData; import org.elasticsearch.index.fielddata.FieldData; -import org.elasticsearch.index.fielddata.ScriptDocValues; +import org.elasticsearch.index.fielddata.LeafOrdinalsFieldData; import org.elasticsearch.index.fielddata.SortedBinaryDocValues; import org.elasticsearch.index.fielddata.plain.AbstractLeafOrdinalsFieldData; +import org.elasticsearch.script.field.DelegateDocValuesField; +import org.elasticsearch.script.field.DocValuesField; import java.io.IOException; import java.io.UncheckedIOException; @@ -79,9 +80,9 @@ public void close() { } @Override - public ScriptDocValues getScriptValues() { - return AbstractLeafOrdinalsFieldData.DEFAULT_SCRIPT_FUNCTION - .apply(getOrdinalsValues()); + public DocValuesField getScriptField(String name) { + return new DelegateDocValuesField( + AbstractLeafOrdinalsFieldData.DEFAULT_SCRIPT_FUNCTION.apply(getOrdinalsValues()), name); } @Override diff --git a/server/src/main/java/org/elasticsearch/script/field/DelegateDocValuesField.java b/server/src/main/java/org/elasticsearch/script/field/DelegateDocValuesField.java new file mode 100644 index 0000000000000..f84f4b4446f1b --- /dev/null +++ b/server/src/main/java/org/elasticsearch/script/field/DelegateDocValuesField.java @@ -0,0 +1,62 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +package org.elasticsearch.script.field; + +import org.elasticsearch.index.fielddata.ScriptDocValues; + +import java.io.IOException; +import java.util.List; + +/** + * A default {@link Field} to provide {@code ScriptDocValues} for fields + * that are not supported by the script fields api. + */ +public class DelegateDocValuesField implements DocValuesField { + + private final ScriptDocValues scriptDocValues; + private final String name; + + public DelegateDocValuesField(ScriptDocValues scriptDocValues, String name) { + this.scriptDocValues = scriptDocValues; + this.name = name; + } + + @Override + public void setNextDocId(int docId) throws IOException { + scriptDocValues.setNextDocId(docId); + } + + @Override + public ScriptDocValues getScriptDocValues() { + return scriptDocValues; + } + + @Override + public String getName() { + throw new UnsupportedOperationException("field [" + name + "] is not supported through the fields api, use [doc] instead"); + } + + @Override + public boolean isEmpty() { + throw new UnsupportedOperationException("field [" + name + "] is not supported through the fields api, use [doc] instead"); + } + + @Override + public int size() { + throw new UnsupportedOperationException("field [" + name + "] is not supported through the fields api, use [doc] instead"); + } + + public Object getValue(Object defaultValue) { + throw new UnsupportedOperationException("field [" + name + "] is not supported through the fields api, use [doc] instead"); + } + + public List getValues() { + throw new UnsupportedOperationException("field [" + name + "] is not supported through the fields api, use [doc] instead"); + } +} diff --git a/server/src/main/java/org/elasticsearch/script/field/DocValuesField.java b/server/src/main/java/org/elasticsearch/script/field/DocValuesField.java index a412f4dc2a08a..9061cf81ec5a9 100644 --- a/server/src/main/java/org/elasticsearch/script/field/DocValuesField.java +++ b/server/src/main/java/org/elasticsearch/script/field/DocValuesField.java @@ -8,10 +8,19 @@ package org.elasticsearch.script.field; +import org.elasticsearch.index.fielddata.ScriptDocValues; + import java.io.IOException; public interface DocValuesField extends Field { /** Set the current document ID. */ void setNextDocId(int docId) throws IOException; + + /** + * Returns a {@code ScriptDocValues} of the appropriate type for this field. + * This is used to support backwards compatibility for accessing field values + * through the {@code doc} variable. + */ + ScriptDocValues getScriptDocValues(); } diff --git a/server/src/main/java/org/elasticsearch/search/lookup/LeafDocLookup.java b/server/src/main/java/org/elasticsearch/search/lookup/LeafDocLookup.java index d2198b237548d..e9818f50ffd9b 100644 --- a/server/src/main/java/org/elasticsearch/search/lookup/LeafDocLookup.java +++ b/server/src/main/java/org/elasticsearch/search/lookup/LeafDocLookup.java @@ -25,15 +25,14 @@ public class LeafDocLookup implements Map> { - private final Map localCacheScriptFieldData = new HashMap<>(4); - private final Map> localCacheFieldData = new HashMap<>(4); private final Function fieldTypeLookup; private final Function> fieldDataLookup; - private final LeafReaderContext reader; private int docId = -1; + private final Map localCacheScriptFieldData = new HashMap<>(4); + LeafDocLookup(Function fieldTypeLookup, Function> fieldDataLookup, LeafReaderContext reader) { this.fieldTypeLookup = fieldTypeLookup; @@ -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"); } // Load the field data on behalf of the script. Otherwise, it would require @@ -78,38 +77,15 @@ public DocValuesField run() { @Override public ScriptDocValues get(Object key) { - // assume its a string... String fieldName = key.toString(); - ScriptDocValues scriptValues = localCacheFieldData.get(fieldName); - if (scriptValues == null) { - final MappedFieldType fieldType = fieldTypeLookup.apply(fieldName); - if (fieldType == null) { - throw new IllegalArgumentException("No field found for [" + fieldName + "] in mapping"); - } - // load fielddata on behalf of the script: otherwise it would need additional permissions - // to deal with pagedbytes/ramusagestimator/etc - scriptValues = AccessController.doPrivileged(new PrivilegedAction>() { - @Override - public ScriptDocValues run() { - return fieldDataLookup.apply(fieldType).load(reader).getScriptValues(); - } - }); - localCacheFieldData.put(fieldName, scriptValues); - } - try { - scriptValues.setNextDocId(docId); - } catch (IOException e) { - throw ExceptionsHelper.convertToElastic(e); - } - return scriptValues; + return getScriptField(fieldName).getScriptDocValues(); } @Override public boolean containsKey(Object key) { - // assume its a string... String fieldName = key.toString(); - ScriptDocValues scriptValues = localCacheFieldData.get(fieldName); - return scriptValues != null || fieldTypeLookup.apply(fieldName) != null; + DocValuesField docValuesField = localCacheScriptFieldData.get(fieldName); + return docValuesField != null || fieldTypeLookup.apply(fieldName) != null; } @Override diff --git a/server/src/test/java/org/elasticsearch/index/fielddata/BinaryDVFieldDataTests.java b/server/src/test/java/org/elasticsearch/index/fielddata/BinaryDVFieldDataTests.java index 39578766c7b61..3565a0ff0d242 100644 --- a/server/src/test/java/org/elasticsearch/index/fielddata/BinaryDVFieldDataTests.java +++ b/server/src/test/java/org/elasticsearch/index/fielddata/BinaryDVFieldDataTests.java @@ -111,7 +111,7 @@ public void testDocValue() throws Exception { // Test whether ScriptDocValues.BytesRefs makes a deepcopy fieldData = indexFieldData.load(reader); - ScriptDocValues scriptValues = fieldData.getScriptValues(); + ScriptDocValues scriptValues = fieldData.getScriptField("test").getScriptDocValues(); Object[][] retValues = new BytesRef[4][0]; for (int i = 0; i < 4; i++) { scriptValues.setNextDocId(i); diff --git a/server/src/test/java/org/elasticsearch/index/query/SearchExecutionContextTests.java b/server/src/test/java/org/elasticsearch/index/query/SearchExecutionContextTests.java index 3f2e6e3fbddd4..2851e1d7142c4 100644 --- a/server/src/test/java/org/elasticsearch/index/query/SearchExecutionContextTests.java +++ b/server/src/test/java/org/elasticsearch/index/query/SearchExecutionContextTests.java @@ -29,6 +29,8 @@ import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.util.BigArrays; +import org.elasticsearch.script.field.DelegateDocValuesField; +import org.elasticsearch.script.field.DocValuesField; import org.elasticsearch.xcontent.NamedXContentRegistry; import org.elasticsearch.xcontent.XContentBuilder; import org.elasticsearch.index.IndexSettings; @@ -490,8 +492,8 @@ public ValuesSourceType getValuesSourceType() { public LeafFieldData load(LeafReaderContext context) { return new LeafFieldData() { @Override - public ScriptDocValues getScriptValues() { - return new ScriptDocValues() { + public DocValuesField getScriptField(String name) { + return new DelegateDocValuesField(new ScriptDocValues() { String value; @Override @@ -513,7 +515,7 @@ public void setNextDocId(int docId) { leafLookup.setDocument(docId); value = runtimeDocValues.apply(leafLookup, docId); } - }; + }, name); } @Override @@ -589,7 +591,6 @@ public ScoreMode scoreMode() { @Override public LeafCollector getLeafCollector(LeafReaderContext context) { - ScriptDocValues scriptValues = indexFieldData.load(context).getScriptValues(); return new LeafCollector() { @Override public void setScorer(Scorable scorer) {} @@ -602,7 +603,7 @@ public void collect(int doc) throws IOException { leafDocLookup.setDocument(doc); scriptDocValues = leafDocLookup.get(field); } else { - scriptDocValues = scriptValues; + scriptDocValues = indexFieldData.load(context).getScriptField("test").getScriptDocValues();; } scriptDocValues.setNextDocId(doc); for (int i = 0; i < scriptDocValues.size(); i++) { diff --git a/server/src/test/java/org/elasticsearch/index/query/functionscore/FunctionScoreTests.java b/server/src/test/java/org/elasticsearch/index/query/functionscore/FunctionScoreTests.java index 600f6302f89b2..d8b04b83ac479 100644 --- a/server/src/test/java/org/elasticsearch/index/query/functionscore/FunctionScoreTests.java +++ b/server/src/test/java/org/elasticsearch/index/query/functionscore/FunctionScoreTests.java @@ -31,7 +31,6 @@ import org.apache.lucene.util.Accountable; import org.apache.lucene.util.BytesRef; import org.elasticsearch.ElasticsearchException; -import org.elasticsearch.core.Nullable; import org.elasticsearch.common.lucene.search.function.CombineFunction; import org.elasticsearch.common.lucene.search.function.FieldValueFactorFunction; import org.elasticsearch.common.lucene.search.function.FunctionScoreQuery; @@ -42,14 +41,15 @@ import org.elasticsearch.common.lucene.search.function.ScoreFunction; import org.elasticsearch.common.lucene.search.function.WeightFactorFunction; import org.elasticsearch.common.util.BigArrays; +import org.elasticsearch.core.Nullable; import org.elasticsearch.index.fielddata.IndexFieldData; import org.elasticsearch.index.fielddata.IndexFieldData.XFieldComparatorSource.Nested; import org.elasticsearch.index.fielddata.IndexNumericFieldData; import org.elasticsearch.index.fielddata.LeafFieldData; import org.elasticsearch.index.fielddata.LeafNumericFieldData; -import org.elasticsearch.index.fielddata.ScriptDocValues; import org.elasticsearch.index.fielddata.SortedBinaryDocValues; import org.elasticsearch.index.fielddata.SortedNumericDoubleValues; +import org.elasticsearch.script.field.DocValuesField; import org.elasticsearch.search.DocValueFormat; import org.elasticsearch.search.MultiValueMode; import org.elasticsearch.search.aggregations.support.ValuesSourceType; @@ -92,7 +92,7 @@ public LeafFieldData load(LeafReaderContext context) { return new LeafFieldData() { @Override - public ScriptDocValues getScriptValues() { + public DocValuesField getScriptField(String name) { throw new UnsupportedOperationException(UNSUPPORTED); } @@ -199,7 +199,7 @@ public double nextValue() { } @Override - public ScriptDocValues getScriptValues() { + public DocValuesField getScriptField(String name) { throw new UnsupportedOperationException(UNSUPPORTED); } diff --git a/server/src/test/java/org/elasticsearch/search/lookup/LeafDocLookupTests.java b/server/src/test/java/org/elasticsearch/search/lookup/LeafDocLookupTests.java index 736a433fd87a3..f7267f9c398d1 100644 --- a/server/src/test/java/org/elasticsearch/search/lookup/LeafDocLookupTests.java +++ b/server/src/test/java/org/elasticsearch/search/lookup/LeafDocLookupTests.java @@ -14,6 +14,7 @@ import org.elasticsearch.index.mapper.MappedFieldType; import org.elasticsearch.index.mapper.MapperBuilderContext; import org.elasticsearch.index.mapper.flattened.FlattenedFieldMapper; +import org.elasticsearch.script.field.DelegateDocValuesField; import org.elasticsearch.test.ESTestCase; import org.junit.Before; @@ -34,15 +35,20 @@ public class LeafDocLookupTests extends ESTestCase { public void setUp() throws Exception { super.setUp(); - MappedFieldType fieldType = mock(MappedFieldType.class); - when(fieldType.name()).thenReturn("field"); - when(fieldType.valueForDisplay(anyObject())).then(returnsFirstArg()); - docValues = mock(ScriptDocValues.class); - IndexFieldData fieldData = createFieldData(docValues); - docLookup = new LeafDocLookup(field -> field.equals("field") || field.equals("alias") ? fieldType : null, - ignored -> fieldData, null); + MappedFieldType fieldType1 = mock(MappedFieldType.class); + when(fieldType1.name()).thenReturn("field"); + when(fieldType1.valueForDisplay(anyObject())).then(returnsFirstArg()); + IndexFieldData fieldData1 = createFieldData(docValues, "field"); + + MappedFieldType fieldType2 = mock(MappedFieldType.class); + when(fieldType1.name()).thenReturn("alias"); + when(fieldType1.valueForDisplay(anyObject())).then(returnsFirstArg()); + IndexFieldData fieldData2 = createFieldData(docValues, "alias"); + + docLookup = new LeafDocLookup(field -> field.equals("field") ? fieldType1 : field.equals("alias") ? fieldType2 : null, + fieldType -> fieldType == fieldType1 ? fieldData1 : fieldType == fieldType2 ? fieldData2 : null, null); } public void testBasicLookup() { @@ -57,10 +63,10 @@ public void testFieldAliases() { public void testFlattenedField() { ScriptDocValues docValues1 = mock(ScriptDocValues.class); - IndexFieldData fieldData1 = createFieldData(docValues1); + IndexFieldData fieldData1 = createFieldData(docValues1, "flattened.key1"); ScriptDocValues docValues2 = mock(ScriptDocValues.class); - IndexFieldData fieldData2 = createFieldData(docValues2); + IndexFieldData fieldData2 = createFieldData(docValues2, "flattened.key2"); FlattenedFieldMapper fieldMapper = new FlattenedFieldMapper.Builder("field") .build(MapperBuilderContext.ROOT); @@ -87,12 +93,13 @@ public void testFlattenedField() { assertEquals(docValues2, docLookup.get("flattened.key2")); } - private IndexFieldData createFieldData(ScriptDocValues scriptDocValues) { + private IndexFieldData createFieldData(ScriptDocValues scriptDocValues, String name) { + DelegateDocValuesField delegateDocValuesField = new DelegateDocValuesField(scriptDocValues, name); LeafFieldData leafFieldData = mock(LeafFieldData.class); - doReturn(scriptDocValues).when(leafFieldData).getScriptValues(); + doReturn(delegateDocValuesField).when(leafFieldData).getScriptField(name); IndexFieldData fieldData = mock(IndexFieldData.class); - when(fieldData.getFieldName()).thenReturn("field"); + when(fieldData.getFieldName()).thenReturn(name); doReturn(leafFieldData).when(fieldData).load(anyObject()); return fieldData; diff --git a/test/framework/src/main/java/org/elasticsearch/index/mapper/MapperTestCase.java b/test/framework/src/main/java/org/elasticsearch/index/mapper/MapperTestCase.java index ee2a6e9d80735..29c8382165c3c 100644 --- a/test/framework/src/main/java/org/elasticsearch/index/mapper/MapperTestCase.java +++ b/test/framework/src/main/java/org/elasticsearch/index/mapper/MapperTestCase.java @@ -675,7 +675,7 @@ public final void testIndexTimeFieldData() throws IOException { .fielddataBuilder("test", () -> { throw new UnsupportedOperationException(); }) .build(new IndexFieldDataCache.None(), new NoneCircuitBreakerService()) .load(ctx) - .getScriptValues(); + .getScriptField("test").getScriptDocValues(); fieldData.setNextDocId(0); @@ -686,7 +686,7 @@ public final void testIndexTimeFieldData() throws IOException { }) .build(new IndexFieldDataCache.None(), new NoneCircuitBreakerService()) .load(reader.getContext()) - .getScriptValues(); + .getScriptField("test").getScriptDocValues(); indexData.setNextDocId(0); // compare index and search time fielddata diff --git a/x-pack/plugin/analytics/src/main/java/org/elasticsearch/xpack/analytics/mapper/HistogramFieldMapper.java b/x-pack/plugin/analytics/src/main/java/org/elasticsearch/xpack/analytics/mapper/HistogramFieldMapper.java index 30eeb4aa69954..1240221dbccb4 100644 --- a/x-pack/plugin/analytics/src/main/java/org/elasticsearch/xpack/analytics/mapper/HistogramFieldMapper.java +++ b/x-pack/plugin/analytics/src/main/java/org/elasticsearch/xpack/analytics/mapper/HistogramFieldMapper.java @@ -27,7 +27,6 @@ import org.elasticsearch.index.fielddata.IndexFieldData.XFieldComparatorSource.Nested; import org.elasticsearch.index.fielddata.IndexHistogramFieldData; import org.elasticsearch.index.fielddata.LeafHistogramFieldData; -import org.elasticsearch.index.fielddata.ScriptDocValues; import org.elasticsearch.index.fielddata.SortedBinaryDocValues; import org.elasticsearch.index.mapper.DocumentParserContext; import org.elasticsearch.index.mapper.FieldMapper; @@ -39,6 +38,7 @@ import org.elasticsearch.index.mapper.TimeSeriesParams; import org.elasticsearch.index.mapper.ValueFetcher; import org.elasticsearch.index.query.SearchExecutionContext; +import org.elasticsearch.script.field.DocValuesField; import org.elasticsearch.search.DocValueFormat; import org.elasticsearch.search.MultiValueMode; import org.elasticsearch.search.lookup.SearchLookup; @@ -207,7 +207,7 @@ public HistogramValue histogram() throws IOException { } @Override - public ScriptDocValues getScriptValues() { + public DocValuesField getScriptField(String name) { throw new UnsupportedOperationException("The [" + CONTENT_TYPE + "] field does not " + "support scripts"); } diff --git a/x-pack/plugin/mapper-aggregate-metric/src/main/java/org/elasticsearch/xpack/aggregatemetric/mapper/AggregateDoubleMetricFieldMapper.java b/x-pack/plugin/mapper-aggregate-metric/src/main/java/org/elasticsearch/xpack/aggregatemetric/mapper/AggregateDoubleMetricFieldMapper.java index 78cdd68d668d8..9a0da27b54a29 100644 --- a/x-pack/plugin/mapper-aggregate-metric/src/main/java/org/elasticsearch/xpack/aggregatemetric/mapper/AggregateDoubleMetricFieldMapper.java +++ b/x-pack/plugin/mapper-aggregate-metric/src/main/java/org/elasticsearch/xpack/aggregatemetric/mapper/AggregateDoubleMetricFieldMapper.java @@ -36,6 +36,8 @@ import org.elasticsearch.index.query.QueryRewriteContext; import org.elasticsearch.index.query.SearchExecutionContext; import org.elasticsearch.script.ScriptCompiler; +import org.elasticsearch.script.field.DelegateDocValuesField; +import org.elasticsearch.script.field.DocValuesField; import org.elasticsearch.search.DocValueFormat; import org.elasticsearch.search.MultiValueMode; import org.elasticsearch.search.lookup.SearchLookup; @@ -419,9 +421,9 @@ public double nextValue() throws IOException { } @Override - public ScriptDocValues getScriptValues() { + public DocValuesField getScriptField(String name) { // getAggregateMetricValues returns all metric as doubles, including `value_count` - return new ScriptDocValues.Doubles(getAggregateMetricValues(defaultMetric)); + return new DelegateDocValuesField(new ScriptDocValues.Doubles(getAggregateMetricValues(defaultMetric)), name); } @Override diff --git a/x-pack/plugin/mapper-unsigned-long/src/main/java/org/elasticsearch/xpack/unsignedlong/UnsignedLongDocValuesField.java b/x-pack/plugin/mapper-unsigned-long/src/main/java/org/elasticsearch/xpack/unsignedlong/UnsignedLongDocValuesField.java index a5407719d5f93..5c1090d21d1ec 100644 --- a/x-pack/plugin/mapper-unsigned-long/src/main/java/org/elasticsearch/xpack/unsignedlong/UnsignedLongDocValuesField.java +++ b/x-pack/plugin/mapper-unsigned-long/src/main/java/org/elasticsearch/xpack/unsignedlong/UnsignedLongDocValuesField.java @@ -9,6 +9,7 @@ import org.apache.lucene.index.SortedNumericDocValues; import org.apache.lucene.util.ArrayUtil; +import org.elasticsearch.index.fielddata.ScriptDocValues; import org.elasticsearch.script.field.DocValuesField; import java.io.IOException; @@ -23,10 +24,14 @@ public class UnsignedLongDocValuesField implements UnsignedLongField, DocValuesField { private final SortedNumericDocValues input; + private final String name; + private long[] values = new long[0]; - private int count; + private int count = 0; - private final String name; + // used for backwards compatibility for old-style "doc" access + // as a delegate to this field class + private UnsignedLongScriptDocValues unsignedLongScriptDocValues = null; public UnsignedLongDocValuesField(SortedNumericDocValues input, String name) { this.input = input; @@ -45,6 +50,15 @@ public void setNextDocId(int docId) throws IOException { } } + @Override + public ScriptDocValues getScriptDocValues() { + if (unsignedLongScriptDocValues == null) { + unsignedLongScriptDocValues = new UnsignedLongScriptDocValues(this); + } + + return unsignedLongScriptDocValues; + } + protected void resize(int newSize) { count = newSize; values = ArrayUtil.grow(values, count); diff --git a/x-pack/plugin/mapper-unsigned-long/src/main/java/org/elasticsearch/xpack/unsignedlong/UnsignedLongLeafFieldData.java b/x-pack/plugin/mapper-unsigned-long/src/main/java/org/elasticsearch/xpack/unsignedlong/UnsignedLongLeafFieldData.java index 63e4e6d8dc142..2072a23e16a54 100644 --- a/x-pack/plugin/mapper-unsigned-long/src/main/java/org/elasticsearch/xpack/unsignedlong/UnsignedLongLeafFieldData.java +++ b/x-pack/plugin/mapper-unsigned-long/src/main/java/org/elasticsearch/xpack/unsignedlong/UnsignedLongLeafFieldData.java @@ -14,7 +14,6 @@ import org.elasticsearch.index.fielddata.FormattedDocValues; import org.elasticsearch.index.fielddata.LeafNumericFieldData; import org.elasticsearch.index.fielddata.NumericDoubleValues; -import org.elasticsearch.index.fielddata.ScriptDocValues; import org.elasticsearch.index.fielddata.SortedBinaryDocValues; import org.elasticsearch.index.fielddata.SortedNumericDoubleValues; import org.elasticsearch.script.field.DocValuesField; @@ -73,11 +72,6 @@ public int docValueCount() { } } - @Override - public ScriptDocValues getScriptValues() { - return new UnsignedLongScriptDocValues(getLongValues()); - } - @Override public DocValuesField getScriptField(String name) { return new UnsignedLongDocValuesField(getLongValues(), name); diff --git a/x-pack/plugin/mapper-unsigned-long/src/main/java/org/elasticsearch/xpack/unsignedlong/UnsignedLongScriptDocValues.java b/x-pack/plugin/mapper-unsigned-long/src/main/java/org/elasticsearch/xpack/unsignedlong/UnsignedLongScriptDocValues.java index af31aafec68d5..3278e4f165338 100644 --- a/x-pack/plugin/mapper-unsigned-long/src/main/java/org/elasticsearch/xpack/unsignedlong/UnsignedLongScriptDocValues.java +++ b/x-pack/plugin/mapper-unsigned-long/src/main/java/org/elasticsearch/xpack/unsignedlong/UnsignedLongScriptDocValues.java @@ -7,68 +7,39 @@ package org.elasticsearch.xpack.unsignedlong; -import org.apache.lucene.index.SortedNumericDocValues; -import org.apache.lucene.util.ArrayUtil; import org.elasticsearch.index.fielddata.ScriptDocValues; import java.io.IOException; -import static org.elasticsearch.search.DocValueFormat.MASK_2_63; - public class UnsignedLongScriptDocValues extends ScriptDocValues { - private final SortedNumericDocValues in; - private long[] values = new long[0]; - private int count; + private final UnsignedLongDocValuesField unsignedLongDocValuesField; /** * Standard constructor. */ - public UnsignedLongScriptDocValues(SortedNumericDocValues in) { - this.in = in; + public UnsignedLongScriptDocValues(UnsignedLongDocValuesField unsignedLongDocValuesField) { + this.unsignedLongDocValuesField = unsignedLongDocValuesField; } @Override public void setNextDocId(int docId) throws IOException { - if (in.advanceExact(docId)) { - resize(in.docValueCount()); - for (int i = 0; i < count; i++) { - values[i] = in.nextValue(); - } - } else { - resize(0); - } - } - - /** - * Set the {@link #size()} and ensure that the {@link #values} array can - * store at least that many entries. - */ - protected void resize(int newSize) { - count = newSize; - values = ArrayUtil.grow(values, count); + throw new UnsupportedOperationException(); } public long getValue() { - return get(0); + throwIfEmpty(); + return unsignedLongDocValuesField.getValue(0L); // default is ignored } @Override public Long get(int index) { throwIfEmpty(); - return format(index); - } - - /** - * Applies the formatting from {@link org.elasticsearch.search.DocValueFormat.UnsignedLongShiftedDocValueFormat#format(long)} so - * that the underlying value can be treated as a primitive long as that method returns either a {@code long} or a {@code BigInteger}. - */ - protected long format(int index) { - return values[index] ^ MASK_2_63; + return unsignedLongDocValuesField.getValue(0L); // default is ignored } @Override public int size() { - return count; + return unsignedLongDocValuesField.size(); } } diff --git a/x-pack/plugin/spatial/src/main/java/org/elasticsearch/xpack/spatial/index/fielddata/plain/AbstractAtomicGeoShapeShapeFieldData.java b/x-pack/plugin/spatial/src/main/java/org/elasticsearch/xpack/spatial/index/fielddata/plain/AbstractAtomicGeoShapeShapeFieldData.java index 62b0abedd788d..921789a2bef41 100644 --- a/x-pack/plugin/spatial/src/main/java/org/elasticsearch/xpack/spatial/index/fielddata/plain/AbstractAtomicGeoShapeShapeFieldData.java +++ b/x-pack/plugin/spatial/src/main/java/org/elasticsearch/xpack/spatial/index/fielddata/plain/AbstractAtomicGeoShapeShapeFieldData.java @@ -12,6 +12,8 @@ import org.elasticsearch.common.geo.GeoPoint; import org.elasticsearch.index.fielddata.ScriptDocValues; import org.elasticsearch.index.fielddata.SortedBinaryDocValues; +import org.elasticsearch.script.field.DelegateDocValuesField; +import org.elasticsearch.script.field.DocValuesField; import org.elasticsearch.xpack.spatial.index.fielddata.GeoShapeValues; import org.elasticsearch.xpack.spatial.index.fielddata.LeafGeoShapeFieldData; @@ -30,8 +32,8 @@ public final SortedBinaryDocValues getBytesValues() { } @Override - public final ScriptDocValues.Geometry getScriptValues() { - return new GeoShapeScriptValues(getGeoShapeValues()); + public final DocValuesField getScriptField(String name) { + return new DelegateDocValuesField(new GeoShapeScriptValues(getGeoShapeValues()), name); } public static LeafGeoShapeFieldData empty(final int maxDoc) { diff --git a/x-pack/plugin/vectors/src/main/java/org/elasticsearch/xpack/vectors/query/VectorDVLeafFieldData.java b/x-pack/plugin/vectors/src/main/java/org/elasticsearch/xpack/vectors/query/VectorDVLeafFieldData.java index 02cd0f5585968..b7015d0f47ba2 100644 --- a/x-pack/plugin/vectors/src/main/java/org/elasticsearch/xpack/vectors/query/VectorDVLeafFieldData.java +++ b/x-pack/plugin/vectors/src/main/java/org/elasticsearch/xpack/vectors/query/VectorDVLeafFieldData.java @@ -13,11 +13,11 @@ import org.apache.lucene.index.LeafReader; import org.apache.lucene.index.VectorValues; import org.apache.lucene.util.Accountable; -import org.apache.lucene.util.BytesRef; import org.elasticsearch.Version; import org.elasticsearch.index.fielddata.LeafFieldData; -import org.elasticsearch.index.fielddata.ScriptDocValues; import org.elasticsearch.index.fielddata.SortedBinaryDocValues; +import org.elasticsearch.script.field.DelegateDocValuesField; +import org.elasticsearch.script.field.DocValuesField; import java.io.IOException; import java.util.Collection; @@ -55,17 +55,17 @@ public SortedBinaryDocValues getBytesValues() { } @Override - public ScriptDocValues getScriptValues() { + public DocValuesField getScriptField(String name) { try { if (indexed) { VectorValues values = reader.getVectorValues(field); if (values == null || values == VectorValues.EMPTY) { - return DenseVectorScriptDocValues.empty(dims); + return new DelegateDocValuesField(DenseVectorScriptDocValues.empty(dims), name); } - return new KnnDenseVectorScriptDocValues(values, dims); + return new DelegateDocValuesField(new KnnDenseVectorScriptDocValues(values, dims), name); } else { BinaryDocValues values = DocValues.getBinary(reader, field); - return new BinaryDenseVectorScriptDocValues(values, indexVersion, dims); + return new DelegateDocValuesField(new BinaryDenseVectorScriptDocValues(values, indexVersion, dims), name); } } catch (IOException e) { throw new IllegalStateException("Cannot load doc values for vector field!", e);