Core: Fix script fields to be returned as a multivalued field when they produce a list.
This change is essentially the same as #3015 but on script fields. Close #8592
This commit is contained in:
parent
bc52ccfd33
commit
8346e92ebb
|
@ -56,3 +56,35 @@ The `memory` / `ram` store (`index.store.type`) option was removed in Elasticsea
|
|||
=== Term Vectors API
|
||||
|
||||
Usage of `/_termvector` is deprecated, and replaced in favor of `/_termvectors`.
|
||||
|
||||
=== Script fields
|
||||
|
||||
Script fields in 1.x were only returned as a single value. So even if the return
|
||||
value of a script used to be list, it would be returned as an array containing
|
||||
a single value that is a list too, such as:
|
||||
|
||||
[source,json]
|
||||
---------------
|
||||
"fields": {
|
||||
"my_field": [
|
||||
[
|
||||
"v1",
|
||||
"v2"
|
||||
]
|
||||
]
|
||||
}
|
||||
---------------
|
||||
|
||||
In elasticsearch 2.x, scripts that return a list of values are considered as
|
||||
multivalued fields. So the same example would return the following response,
|
||||
with values in a single array.
|
||||
|
||||
[source,json]
|
||||
---------------
|
||||
"fields": {
|
||||
"my_field": [
|
||||
"v1",
|
||||
"v2"
|
||||
]
|
||||
}
|
||||
---------------
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
package org.elasticsearch.search.fetch.script;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
|
||||
import org.elasticsearch.ElasticsearchException;
|
||||
import org.elasticsearch.common.inject.Inject;
|
||||
import org.elasticsearch.search.SearchHitField;
|
||||
|
@ -29,7 +30,10 @@ import org.elasticsearch.search.internal.InternalSearchHitField;
|
|||
import org.elasticsearch.search.internal.SearchContext;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
|
@ -86,10 +90,17 @@ public class ScriptFieldsFetchSubPhase implements FetchSubPhase {
|
|||
|
||||
SearchHitField hitField = hitContext.hit().fields().get(scriptField.name());
|
||||
if (hitField == null) {
|
||||
hitField = new InternalSearchHitField(scriptField.name(), new ArrayList<>(2));
|
||||
final List<Object> values;
|
||||
if (value == null) {
|
||||
values = Collections.emptyList();
|
||||
} else if (value instanceof Collection) {
|
||||
values = new ArrayList<>((Collection<?>) value);
|
||||
} else {
|
||||
values = Collections.singletonList(value);
|
||||
}
|
||||
hitField = new InternalSearchHitField(scriptField.name(), values);
|
||||
hitContext.hit().fields().put(scriptField.name(), hitField);
|
||||
}
|
||||
hitField.values().add(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -385,7 +385,7 @@ public class IndexLookupTests extends ElasticsearchIntegrationTest {
|
|||
assertHitCount(sr, expectedHitSize);
|
||||
int nullCounter = 0;
|
||||
for (SearchHit hit : sr.getHits().getHits()) {
|
||||
Object result = hit.getFields().get("tvtest").getValues().get(0);
|
||||
Object result = hit.getFields().get("tvtest").getValues();
|
||||
Object expectedResult = expectedArray.get(hit.getId());
|
||||
assertThat("for doc " + hit.getId(), result, equalTo(expectedResult));
|
||||
if (expectedResult != null) {
|
||||
|
|
|
@ -298,12 +298,12 @@ public class SearchFieldsTests extends ElasticsearchIntegrationTest {
|
|||
assertThat(sObj2Arr2.get(0).toString(), equalTo("arr_value1"));
|
||||
assertThat(sObj2Arr2.get(1).toString(), equalTo("arr_value2"));
|
||||
|
||||
sObj2Arr2 = response.getHits().getAt(0).field("s_obj2_arr2").value();
|
||||
sObj2Arr2 = response.getHits().getAt(0).field("s_obj2_arr2").values();
|
||||
assertThat(sObj2Arr2.size(), equalTo(2));
|
||||
assertThat(sObj2Arr2.get(0).toString(), equalTo("arr_value1"));
|
||||
assertThat(sObj2Arr2.get(1).toString(), equalTo("arr_value2"));
|
||||
|
||||
List sObj2Arr3 = response.getHits().getAt(0).field("s_arr3").value();
|
||||
List sObj2Arr3 = response.getHits().getAt(0).field("s_arr3").values();
|
||||
assertThat(((Map) sObj2Arr3.get(0)).get("arr3_field1").toString(), equalTo("arr3_value1"));
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue