Adds deprecation logging to ScriptDocValues#getValues. (#34279)

`ScriptDocValues#getValues` was added for backwards compatibility but no
longer needed. Scripts using the syntax `doc['foo'].values` when
`doc['foo']` is a list should be using `doc['foo']` instead.

Closes #22919
This commit is contained in:
Jeff Hajewski 2018-11-27 13:30:13 -06:00 committed by Nik Everett
parent 3337fa7351
commit 49087f16f5
23 changed files with 292 additions and 39 deletions

View File

@ -108,7 +108,7 @@ POST /stackoverflow/_search?size=0
"max_docs_per_value" : 3,
"script" : {
"lang": "painless",
"source": "doc['tags'].values.hashCode()"
"source": "doc['tags'].hashCode()"
}
},
"aggs": {

View File

@ -144,7 +144,7 @@ access `text` fields from scripts.
_Stored fields_ -- fields explicitly marked as
<<mapping-store,`"store": true`>> -- can be accessed using the
`_fields['field_name'].value` or `_fields['field_name'].values` syntax.
`_fields['field_name'].value` or `_fields['field_name']` syntax.
The document <<mapping-source-field,`_source`>>, which is really just a
special stored field, can be accessed using the `_source.field_name` syntax.

View File

@ -370,7 +370,7 @@
script_fields:
foobar:
script:
source: "doc['f'].values.size()"
source: "doc['f'].size()"
lang: painless

View File

@ -19,6 +19,7 @@
package org.elasticsearch.index.fielddata;
import org.apache.logging.log4j.LogManager;
import org.apache.lucene.index.SortedNumericDocValues;
import org.apache.lucene.util.ArrayUtil;
import org.apache.lucene.util.BytesRef;
@ -26,15 +27,19 @@ import org.apache.lucene.util.BytesRefBuilder;
import org.elasticsearch.common.geo.GeoHashUtils;
import org.elasticsearch.common.geo.GeoPoint;
import org.elasticsearch.common.geo.GeoUtils;
import org.elasticsearch.common.logging.DeprecationLogger;
import org.elasticsearch.script.JodaCompatibleZonedDateTime;
import java.io.IOException;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.time.Instant;
import java.time.ZoneOffset;
import java.util.AbstractList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.function.BiConsumer;
import java.util.function.UnaryOperator;
/**
@ -48,6 +53,25 @@ import java.util.function.UnaryOperator;
*/
public abstract class ScriptDocValues<T> extends AbstractList<T> {
private static final DeprecationLogger deprecationLogger = new DeprecationLogger(LogManager.getLogger(ScriptDocValues.class));
/**
* Callback for deprecated fields. In production this should always point to
* {@link #deprecationLogger} but tests will override it so they can test
* that we use the required permissions when calling it.
*/
private final BiConsumer<String, String> deprecationCallback;
public ScriptDocValues() {
deprecationCallback = deprecationLogger::deprecatedAndMaybeLog;
}
/**
* Constructor for testing deprecation callback.
*/
ScriptDocValues(BiConsumer<String, String> deprecationCallback) {
this.deprecationCallback = deprecationCallback;
}
/**
* Set the current doc ID.
*/
@ -57,6 +81,8 @@ public abstract class ScriptDocValues<T> extends AbstractList<T> {
* Return a copy of the list of the values for the current document.
*/
public final List<T> getValues() {
deprecated("ScriptDocValues#getValues", "Deprecated getValues used, the field is a list and should be accessed directly."
+ " For example, use doc['foo'] instead of doc['foo'].values.");
return this;
}
@ -86,6 +112,21 @@ public abstract class ScriptDocValues<T> extends AbstractList<T> {
throw new UnsupportedOperationException("doc values are unmodifiable");
}
/**
* Log a deprecation log, with the server's permissions and not the permissions
* of the script calling this method. We need to do this to prevent errors
* when rolling the log file.
*/
private void deprecated(String key, String message) {
AccessController.doPrivileged(new PrivilegedAction<Void>() {
@Override
public Void run() {
deprecationCallback.accept(key, message);
return null;
}
});
}
public static final class Longs extends ScriptDocValues<Long> {
private final SortedNumericDocValues in;
private long[] values = new long[0];
@ -98,6 +139,14 @@ public abstract class ScriptDocValues<T> extends AbstractList<T> {
this.in = in;
}
/**
* Constructor for testing deprecation callback.
*/
Longs(SortedNumericDocValues in, BiConsumer<String, String> deprecationCallback) {
super(deprecationCallback);
this.in = in;
}
@Override
public void setNextDocId(int docId) throws IOException {
if (in.advanceExact(docId)) {
@ -155,6 +204,14 @@ public abstract class ScriptDocValues<T> extends AbstractList<T> {
this.in = in;
}
/**
* Constructor for testing deprecation callback.
*/
Dates(SortedNumericDocValues in, BiConsumer<String, String> deprecationCallback) {
super(deprecationCallback);
this.in = in;
}
/**
* Fetch the first field value or 0 millis after epoch if there are no
* in.
@ -273,6 +330,14 @@ public abstract class ScriptDocValues<T> extends AbstractList<T> {
this.in = in;
}
/**
* Constructor for testing deprecation callback.
*/
GeoPoints(MultiGeoPointValues in, BiConsumer<String, String> deprecationCallback) {
super(deprecationCallback);
this.in = in;
}
@Override
public void setNextDocId(int docId) throws IOException {
if (in.advanceExact(docId)) {

View File

@ -0,0 +1,93 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.elasticsearch.index.fielddata;
import org.elasticsearch.index.fielddata.ScriptDocValues.Dates;
import org.elasticsearch.test.ESTestCase;
import java.security.AccessControlContext;
import java.security.AccessController;
import java.security.PermissionCollection;
import java.security.Permissions;
import java.security.PrivilegedAction;
import java.security.ProtectionDomain;
import java.util.HashSet;
import java.util.Set;
import java.util.function.BiConsumer;
import static org.hamcrest.Matchers.contains;
public class ScriptDocValuesDatesTests extends ESTestCase {
public void testGetValues() {
Set<String> keys = new HashSet<>();
Set<String> warnings = new HashSet<>();
Dates dates = biconsumerWrap((deprecationKey, deprecationMessage) -> {
keys.add(deprecationKey);
warnings.add(deprecationMessage);
// Create a temporary directory to prove we are running with the server's permissions.
createTempDir();
});
/*
* Invoke getValues() without any permissions to verify it still works.
* This is done using the callback created above, which creates a temp
* directory, which is not possible with "noPermission".
*/
PermissionCollection noPermissions = new Permissions();
AccessControlContext noPermissionsAcc = new AccessControlContext(
new ProtectionDomain[] {
new ProtectionDomain(null, noPermissions)
}
);
AccessController.doPrivileged(new PrivilegedAction<Void>(){
public Void run() {
dates.getValues();
return null;
}
}, noPermissionsAcc);
assertThat(warnings, contains(
"Deprecated getValues used, the field is a list and should be accessed directly."
+ " For example, use doc['foo'] instead of doc['foo'].values."));
assertThat(keys, contains("ScriptDocValues#getValues"));
}
private Dates biconsumerWrap(BiConsumer<String, String> deprecationHandler) {
return new Dates(new AbstractSortedNumericDocValues() {
@Override
public boolean advanceExact(int doc) {
return true;
}
@Override
public int docValueCount() {
return 0;
}
@Override
public long nextValue() {
return 0L;
}
}, deprecationHandler);
}
}

View File

@ -21,10 +21,22 @@ package org.elasticsearch.index.fielddata;
import org.elasticsearch.common.geo.GeoPoint;
import org.elasticsearch.common.geo.GeoUtils;
import org.elasticsearch.index.fielddata.ScriptDocValues.GeoPoints;
import org.elasticsearch.test.ESTestCase;
import java.io.IOException;
import java.security.AccessControlContext;
import java.security.AccessController;
import java.security.PermissionCollection;
import java.security.Permissions;
import java.security.PrivilegedAction;
import java.security.ProtectionDomain;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import java.util.function.BiConsumer;
import static org.hamcrest.Matchers.contains;
public class ScriptDocValuesGeoPointsTests extends ESTestCase {
@ -70,8 +82,18 @@ public class ScriptDocValuesGeoPointsTests extends ESTestCase {
final double lat2 = randomLat();
final double lon1 = randomLon();
final double lon2 = randomLon();
Set<String> warnings = new HashSet<>();
Set<String> keys = new HashSet<>();
final MultiGeoPointValues values = wrap(new GeoPoint(lat1, lon1), new GeoPoint(lat2, lon2));
final ScriptDocValues.GeoPoints script = new ScriptDocValues.GeoPoints(values);
final ScriptDocValues.GeoPoints script = geoPointsWrap(values, (deprecationKey, deprecationMessage) -> {
keys.add(deprecationKey);
warnings.add(deprecationMessage);
// Create a temporary directory to prove we are running with the server's permissions.
createTempDir();
});
script.setNextDocId(1);
assertEquals(true, script.isEmpty());
script.setNextDocId(0);
@ -82,6 +104,30 @@ public class ScriptDocValuesGeoPointsTests extends ESTestCase {
assertEquals(lon1, script.getLon(), 0);
assertTrue(Arrays.equals(new double[] {lat1, lat2}, script.getLats()));
assertTrue(Arrays.equals(new double[] {lon1, lon2}, script.getLons()));
/*
* Invoke getValues() without any permissions to verify it still works.
* This is done using the callback created above, which creates a temp
* directory, which is not possible with "noPermission".
*/
PermissionCollection noPermissions = new Permissions();
AccessControlContext noPermissionsAcc = new AccessControlContext(
new ProtectionDomain[] {
new ProtectionDomain(null, noPermissions)
}
);
AccessController.doPrivileged(new PrivilegedAction<Void>(){
public Void run() {
script.getValues();
return null;
}
}, noPermissionsAcc);
assertThat(warnings, contains(
"Deprecated getValues used, the field is a list and should be accessed directly."
+ " For example, use doc['foo'] instead of doc['foo'].values."));
assertThat(keys, contains("ScriptDocValues#getValues"));
}
public void testGeoDistance() throws IOException {
@ -110,4 +156,8 @@ public class ScriptDocValuesGeoPointsTests extends ESTestCase {
assertEquals(42, emptyScript.planeDistanceWithDefault(otherLat, otherLon, 42), 0);
}
private GeoPoints geoPointsWrap(MultiGeoPointValues in, BiConsumer<String, String> deprecationHandler) {
return new GeoPoints(in, deprecationHandler);
}
}

View File

@ -23,6 +23,17 @@ import org.elasticsearch.index.fielddata.ScriptDocValues.Longs;
import org.elasticsearch.test.ESTestCase;
import java.io.IOException;
import java.security.AccessControlContext;
import java.security.AccessController;
import java.security.PermissionCollection;
import java.security.Permissions;
import java.security.PrivilegedAction;
import java.security.ProtectionDomain;
import java.util.HashSet;
import java.util.Set;
import java.util.function.BiConsumer;
import static org.hamcrest.Matchers.contains;
public class ScriptDocValuesLongsTests extends ESTestCase {
public void testLongs() throws IOException {
@ -33,7 +44,17 @@ public class ScriptDocValuesLongsTests extends ESTestCase {
values[d][i] = randomLong();
}
}
Longs longs = wrap(values);
Set<String> warnings = new HashSet<>();
Set<String> keys = new HashSet<>();
Longs longs = wrap(values, (deprecationKey, deprecationMessage) -> {
keys.add(deprecationKey);
warnings.add(deprecationMessage);
// Create a temporary directory to prove we are running with the server's permissions.
createTempDir();
});
for (int round = 0; round < 10; round++) {
int d = between(0, values.length - 1);
@ -55,9 +76,33 @@ public class ScriptDocValuesLongsTests extends ESTestCase {
Exception e = expectThrows(UnsupportedOperationException.class, () -> longs.getValues().add(100L));
assertEquals("doc values are unmodifiable", e.getMessage());
}
/*
* Invoke getValues() without any permissions to verify it still works.
* This is done using the callback created above, which creates a temp
* directory, which is not possible with "noPermission".
*/
PermissionCollection noPermissions = new Permissions();
AccessControlContext noPermissionsAcc = new AccessControlContext(
new ProtectionDomain[] {
new ProtectionDomain(null, noPermissions)
}
);
AccessController.doPrivileged(new PrivilegedAction<Void>(){
public Void run() {
longs.getValues();
return null;
}
}, noPermissionsAcc);
assertThat(warnings, contains(
"Deprecated getValues used, the field is a list and should be accessed directly."
+ " For example, use doc['foo'] instead of doc['foo'].values."));
assertThat(keys, contains("ScriptDocValues#getValues"));
}
private Longs wrap(long[][] values) {
private Longs wrap(long[][] values, BiConsumer<String, String> deprecationCallback) {
return new Longs(new AbstractSortedNumericDocValues() {
long[] current;
int i;
@ -76,6 +121,6 @@ public class ScriptDocValuesLongsTests extends ESTestCase {
public long nextValue() {
return current[i++];
}
});
}, deprecationCallback);
}
}

View File

@ -37,7 +37,7 @@ public class AggregationTestScriptsPlugin extends MockScriptPlugin {
// Equivalent to:
//
// List values = doc['values'].values;
// List values = doc['values'];
// double[] res = new double[values.size()];
// for (int i = 0; i < res.length; i++) {
// res[i] = values.get(i) - dec;
@ -85,7 +85,7 @@ public class AggregationTestScriptsPlugin extends MockScriptPlugin {
return value.getValue() + inc;
});
scripts.put("doc['values'].values", vars -> {
scripts.put("doc['values']", vars -> {
Map<?, ?> doc = (Map<?,?>) vars.get("doc");
return doc.get("values");
});

View File

@ -53,7 +53,7 @@ public class IpTermsIT extends AbstractTermsTestCase {
return doc.get("ip");
});
scripts.put("doc['ip'].values", vars -> {
scripts.put("doc['ip']", vars -> {
Map<?, ?> doc = (Map<?,?>) vars.get("doc");
return ((ScriptDocValues<?>) doc.get("ip")).get(0);
});
@ -96,7 +96,7 @@ public class IpTermsIT extends AbstractTermsTestCase {
client().prepareIndex("index", "type", "3").setSource("ip", "2001:db8::2:1"));
Script script = new Script(ScriptType.INLINE, CustomScriptPlugin.NAME,
"doc['ip'].values", Collections.emptyMap());
"doc['ip']", Collections.emptyMap());
SearchResponse response = client().prepareSearch("index").addAggregation(
AggregationBuilders.terms("my_terms").script(script).executionHint(randomExecutionHint())).get();
assertSearchResponse(response);

View File

@ -81,19 +81,19 @@ public class MinDocCountIT extends AbstractTermsTestCase {
protected Map<String, Function<Map<String, Object>, Object>> pluginScripts() {
Map<String, Function<Map<String, Object>, Object>> scripts = new HashMap<>();
scripts.put("doc['d'].values", vars -> {
scripts.put("doc['d']", vars -> {
Map<?, ?> doc = (Map) vars.get("doc");
ScriptDocValues.Doubles value = (ScriptDocValues.Doubles) doc.get("d");
return value.getValues();
});
scripts.put("doc['l'].values", vars -> {
scripts.put("doc['l']", vars -> {
Map<?, ?> doc = (Map) vars.get("doc");
ScriptDocValues.Longs value = (ScriptDocValues.Longs) doc.get("l");
return value.getValues();
});
scripts.put("doc['s'].values", vars -> {
scripts.put("doc['s']", vars -> {
Map<?, ?> doc = (Map) vars.get("doc");
ScriptDocValues.Strings value = (ScriptDocValues.Strings) doc.get("s");
return value.getValues();
@ -154,7 +154,7 @@ public class MinDocCountIT extends AbstractTermsTestCase {
@Override
TermsAggregationBuilder apply(TermsAggregationBuilder builder, String field) {
return builder.script(new org.elasticsearch.script.Script(ScriptType.INLINE,
CustomScriptPlugin.NAME, "doc['" + field + "'].values", Collections.emptyMap()));
CustomScriptPlugin.NAME, "doc['" + field + "']", Collections.emptyMap()));
}
};
abstract TermsAggregationBuilder apply(TermsAggregationBuilder builder, String field);

View File

@ -84,7 +84,7 @@ public class RangeIT extends ESIntegTestCase {
return value.getValue();
});
scripts.put("doc['" + MULTI_VALUED_FIELD_NAME + "'].values", vars -> {
scripts.put("doc['" + MULTI_VALUED_FIELD_NAME + "']", vars -> {
Map<?, ?> doc = (Map) vars.get("doc");
ScriptDocValues.Longs value = (ScriptDocValues.Longs) doc.get(MULTI_VALUED_FIELD_NAME);
return value.getValues();
@ -693,7 +693,7 @@ public class RangeIT extends ESIntegTestCase {
public void testScriptMultiValued() throws Exception {
Script script =
new Script(ScriptType.INLINE, CustomScriptPlugin.NAME, "doc['" + MULTI_VALUED_FIELD_NAME + "'].values", Collections.emptyMap());
new Script(ScriptType.INLINE, CustomScriptPlugin.NAME, "doc['" + MULTI_VALUED_FIELD_NAME + "']", Collections.emptyMap());
SearchResponse response = client()
.prepareSearch("idx")

View File

@ -72,7 +72,7 @@ public class CardinalityIT extends ESIntegTestCase {
return doc.get("str_value");
});
scripts.put("doc['str_values'].values", vars -> {
scripts.put("doc['str_values']", vars -> {
Map<?, ?> doc = (Map<?, ?>) vars.get("doc");
ScriptDocValues.Strings strValue = (ScriptDocValues.Strings) doc.get("str_values");
return strValue.getValues();
@ -83,7 +83,7 @@ public class CardinalityIT extends ESIntegTestCase {
return doc.get(singleNumericField());
});
scripts.put("doc[' + multiNumericField(false) + '].values", vars -> {
scripts.put("doc[' + multiNumericField(false) + ']", vars -> {
Map<?, ?> doc =(Map<?, ?>) vars.get("doc");
return ((ScriptDocValues<?>) doc.get(multiNumericField(false))).getValues();
});
@ -322,7 +322,7 @@ public class CardinalityIT extends ESIntegTestCase {
.addAggregation(
cardinality("cardinality")
.precisionThreshold(precisionThreshold)
.script(new Script(ScriptType.INLINE, CustomScriptPlugin.NAME, "doc['str_values'].values", emptyMap())))
.script(new Script(ScriptType.INLINE, CustomScriptPlugin.NAME, "doc['str_values']", emptyMap())))
.execute().actionGet();
assertSearchResponse(response);
@ -349,7 +349,7 @@ public class CardinalityIT extends ESIntegTestCase {
public void testMultiValuedNumericScript() throws Exception {
Script script =
new Script(ScriptType.INLINE, CustomScriptPlugin.NAME, "doc[' + multiNumericField(false) + '].values", Collections.emptyMap());
new Script(ScriptType.INLINE, CustomScriptPlugin.NAME, "doc[' + multiNumericField(false) + ']", Collections.emptyMap());
SearchResponse response = client().prepareSearch("idx").setTypes("type")
.addAggregation(cardinality("cardinality").precisionThreshold(precisionThreshold).script(script))
.execute().actionGet();

View File

@ -502,7 +502,7 @@ public class ExtendedStatsIT extends AbstractNumericTestCase {
.addAggregation(
extendedStats("stats")
.script(new Script(ScriptType.INLINE,
AggregationTestScriptsPlugin.NAME, "doc['values'].values", Collections.emptyMap()))
AggregationTestScriptsPlugin.NAME, "doc['values']", Collections.emptyMap()))
.sigma(sigma))
.execute().actionGet();

View File

@ -457,7 +457,7 @@ public class HDRPercentileRanksIT extends AbstractNumericTestCase {
int sigDigits = randomSignificantDigits();
final double[] pcts = randomPercents(minValues, maxValues);
Script script = new Script(ScriptType.INLINE, AggregationTestScriptsPlugin.NAME, "doc['values'].values", emptyMap());
Script script = new Script(ScriptType.INLINE, AggregationTestScriptsPlugin.NAME, "doc['values']", emptyMap());
SearchResponse searchResponse = client()
.prepareSearch("idx")

View File

@ -416,7 +416,7 @@ public class HDRPercentilesIT extends AbstractNumericTestCase {
final double[] pcts = randomPercentiles();
int sigDigits = randomSignificantDigits();
Script script = new Script(ScriptType.INLINE, AggregationTestScriptsPlugin.NAME, "doc['values'].values", emptyMap());
Script script = new Script(ScriptType.INLINE, AggregationTestScriptsPlugin.NAME, "doc['values']", emptyMap());
SearchResponse searchResponse = client()
.prepareSearch("idx")

View File

@ -294,7 +294,7 @@ public class MaxIT extends AbstractNumericTestCase {
.addAggregation(
max("max")
.script(new Script(ScriptType.INLINE,
AggregationTestScriptsPlugin.NAME, "doc['values'].values", Collections.emptyMap())))
AggregationTestScriptsPlugin.NAME, "doc['values']", Collections.emptyMap())))
.get();
assertHitCount(searchResponse, 10);

View File

@ -441,7 +441,7 @@ public class MedianAbsoluteDeviationIT extends AbstractNumericTestCase {
.script(new Script(
ScriptType.INLINE,
AggregationTestScriptsPlugin.NAME,
"doc['values'].values",
"doc['values']",
Collections.emptyMap())))
.execute()
.actionGet();

View File

@ -305,7 +305,7 @@ public class MinIT extends AbstractNumericTestCase {
@Override
public void testScriptMultiValued() throws Exception {
Script script = new Script(ScriptType.INLINE, AggregationTestScriptsPlugin.NAME, "doc['values'].values", emptyMap());
Script script = new Script(ScriptType.INLINE, AggregationTestScriptsPlugin.NAME, "doc['values']", emptyMap());
SearchResponse searchResponse = client().prepareSearch("idx").setQuery(matchAllQuery())
.addAggregation(min("min").script(script))
.get();

View File

@ -392,7 +392,7 @@ public class StatsIT extends AbstractNumericTestCase {
@Override
public void testScriptMultiValued() throws Exception {
Script script = new Script(ScriptType.INLINE, AggregationTestScriptsPlugin.NAME, "doc['values'].values", emptyMap());
Script script = new Script(ScriptType.INLINE, AggregationTestScriptsPlugin.NAME, "doc['values']", emptyMap());
SearchResponse searchResponse = client().prepareSearch("idx")
.setQuery(matchAllQuery())

View File

@ -392,7 +392,7 @@ public class TDigestPercentileRanksIT extends AbstractNumericTestCase {
@Override
public void testScriptMultiValued() throws Exception {
final double[] pcts = randomPercents(minValues, maxValues);
Script script = new Script(ScriptType.INLINE, AggregationTestScriptsPlugin.NAME, "doc['values'].values", emptyMap());
Script script = new Script(ScriptType.INLINE, AggregationTestScriptsPlugin.NAME, "doc['values']", emptyMap());
SearchResponse searchResponse = client().prepareSearch("idx")
.setQuery(matchAllQuery())
.addAggregation(

View File

@ -371,7 +371,7 @@ public class TDigestPercentilesIT extends AbstractNumericTestCase {
@Override
public void testScriptMultiValued() throws Exception {
final double[] pcts = randomPercentiles();
Script script = new Script(ScriptType.INLINE, AggregationTestScriptsPlugin.NAME, "doc['values'].values", emptyMap());
Script script = new Script(ScriptType.INLINE, AggregationTestScriptsPlugin.NAME, "doc['values']", emptyMap());
SearchResponse searchResponse = client().prepareSearch("idx")
.setQuery(matchAllQuery())

View File

@ -131,12 +131,12 @@ public class SearchFieldsIT extends ESIntegTestCase {
scripts.put("return null", vars -> null);
scripts.put("doc['l'].values", vars -> docScript(vars, "l"));
scripts.put("doc['ml'].values", vars -> docScript(vars, "ml"));
scripts.put("doc['d'].values", vars -> docScript(vars, "d"));
scripts.put("doc['md'].values", vars -> docScript(vars, "md"));
scripts.put("doc['s'].values", vars -> docScript(vars, "s"));
scripts.put("doc['ms'].values", vars -> docScript(vars, "ms"));
scripts.put("doc['l']", vars -> docScript(vars, "l"));
scripts.put("doc['ml']", vars -> docScript(vars, "ml"));
scripts.put("doc['d']", vars -> docScript(vars, "d"));
scripts.put("doc['md']", vars -> docScript(vars, "md"));
scripts.put("doc['s']", vars -> docScript(vars, "s"));
scripts.put("doc['ms']", vars -> docScript(vars, "ms"));
return scripts;
}
@ -925,7 +925,7 @@ public class SearchFieldsIT extends ESIntegTestCase {
SearchRequestBuilder req = client().prepareSearch("index");
for (String field : Arrays.asList("s", "ms", "l", "ml", "d", "md")) {
req.addScriptField(field,
new Script(ScriptType.INLINE, CustomScriptPlugin.NAME, "doc['" + field + "'].values", Collections.emptyMap()));
new Script(ScriptType.INLINE, CustomScriptPlugin.NAME, "doc['" + field + "']", Collections.emptyMap()));
}
SearchResponse resp = req.get();
assertSearchResponse(resp);

View File

@ -85,7 +85,7 @@ public class SimpleSortIT extends ESIntegTestCase {
return ((ScriptDocValues.Strings) doc.get("id")).getValue();
});
scripts.put("doc['id'].values[0]", vars -> {
scripts.put("doc['id'][0]", vars -> {
Map<?, ?> doc = (Map) vars.get("doc");
return ((ScriptDocValues.Strings) doc.get("id")).getValues().get(0);
});
@ -399,7 +399,7 @@ public class SimpleSortIT extends ESIntegTestCase {
searchResponse = client().prepareSearch()
.setQuery(matchAllQuery())
.addScriptField("id", new Script(ScriptType.INLINE, CustomScriptPlugin.NAME, "doc['id'].values[0]", Collections.emptyMap()))
.addScriptField("id", new Script(ScriptType.INLINE, CustomScriptPlugin.NAME, "doc['id'][0]", Collections.emptyMap()))
.addSort("svalue", SortOrder.ASC)
.get();