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
|
=== Term Vectors API
|
||||||
|
|
||||||
Usage of `/_termvector` is deprecated, and replaced in favor of `/_termvectors`.
|
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;
|
package org.elasticsearch.search.fetch.script;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
|
||||||
import org.elasticsearch.ElasticsearchException;
|
import org.elasticsearch.ElasticsearchException;
|
||||||
import org.elasticsearch.common.inject.Inject;
|
import org.elasticsearch.common.inject.Inject;
|
||||||
import org.elasticsearch.search.SearchHitField;
|
import org.elasticsearch.search.SearchHitField;
|
||||||
|
@ -29,7 +30,10 @@ import org.elasticsearch.search.internal.InternalSearchHitField;
|
||||||
import org.elasticsearch.search.internal.SearchContext;
|
import org.elasticsearch.search.internal.SearchContext;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -86,10 +90,17 @@ public class ScriptFieldsFetchSubPhase implements FetchSubPhase {
|
||||||
|
|
||||||
SearchHitField hitField = hitContext.hit().fields().get(scriptField.name());
|
SearchHitField hitField = hitContext.hit().fields().get(scriptField.name());
|
||||||
if (hitField == null) {
|
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);
|
hitContext.hit().fields().put(scriptField.name(), hitField);
|
||||||
}
|
}
|
||||||
hitField.values().add(value);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -385,7 +385,7 @@ public class IndexLookupTests extends ElasticsearchIntegrationTest {
|
||||||
assertHitCount(sr, expectedHitSize);
|
assertHitCount(sr, expectedHitSize);
|
||||||
int nullCounter = 0;
|
int nullCounter = 0;
|
||||||
for (SearchHit hit : sr.getHits().getHits()) {
|
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());
|
Object expectedResult = expectedArray.get(hit.getId());
|
||||||
assertThat("for doc " + hit.getId(), result, equalTo(expectedResult));
|
assertThat("for doc " + hit.getId(), result, equalTo(expectedResult));
|
||||||
if (expectedResult != null) {
|
if (expectedResult != null) {
|
||||||
|
|
|
@ -298,12 +298,12 @@ public class SearchFieldsTests extends ElasticsearchIntegrationTest {
|
||||||
assertThat(sObj2Arr2.get(0).toString(), equalTo("arr_value1"));
|
assertThat(sObj2Arr2.get(0).toString(), equalTo("arr_value1"));
|
||||||
assertThat(sObj2Arr2.get(1).toString(), equalTo("arr_value2"));
|
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.size(), equalTo(2));
|
||||||
assertThat(sObj2Arr2.get(0).toString(), equalTo("arr_value1"));
|
assertThat(sObj2Arr2.get(0).toString(), equalTo("arr_value1"));
|
||||||
assertThat(sObj2Arr2.get(1).toString(), equalTo("arr_value2"));
|
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"));
|
assertThat(((Map) sObj2Arr3.get(0)).get("arr3_field1").toString(), equalTo("arr3_value1"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue