Filter empty fields in SearchHit#toXContent (#58418)
This commit restores the filtering of empty fields during the xcontent serialization of SearchHit. The filtering was removed unintentionally in #41656.
This commit is contained in:
parent
03e6d1b535
commit
6451187e84
|
@ -647,7 +647,12 @@ public final class SearchHit implements Writeable, ToXContentObject, Iterable<Do
|
|||
} else {
|
||||
builder.field(Fields._SCORE, score);
|
||||
}
|
||||
|
||||
for (DocumentField field : metaFields.values()) {
|
||||
// ignore empty metadata fields
|
||||
if (field.getValues().size() == 0) {
|
||||
continue;
|
||||
}
|
||||
// _ignored is the only multi-valued meta field
|
||||
// TODO: can we avoid having an exception here?
|
||||
if (field.getName().equals(IgnoredFieldMapper.NAME)) {
|
||||
|
@ -659,10 +664,15 @@ public final class SearchHit implements Writeable, ToXContentObject, Iterable<Do
|
|||
if (source != null) {
|
||||
XContentHelper.writeRawField(SourceFieldMapper.NAME, source, builder, params);
|
||||
}
|
||||
if (!documentFields.isEmpty()) {
|
||||
if (documentFields.isEmpty() == false &&
|
||||
// ignore fields all together if they are all empty
|
||||
documentFields.values().stream()
|
||||
.anyMatch(df -> df.getValues().size() > 0)) {
|
||||
builder.startObject(Fields.FIELDS);
|
||||
for (DocumentField field : documentFields.values()) {
|
||||
field.toXContent(builder, params);
|
||||
if (field.getValues().size() > 0) {
|
||||
field.toXContent(builder, params);
|
||||
}
|
||||
}
|
||||
builder.endObject();
|
||||
}
|
||||
|
|
|
@ -55,8 +55,10 @@ import java.util.function.Predicate;
|
|||
import static org.elasticsearch.common.xcontent.XContentHelper.toXContent;
|
||||
import static org.elasticsearch.test.XContentTestUtils.insertRandomFields;
|
||||
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertToXContentEquivalent;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.instanceOf;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
import static org.hamcrest.Matchers.notNullValue;
|
||||
import static org.hamcrest.Matchers.nullValue;
|
||||
|
||||
|
@ -359,6 +361,61 @@ public class SearchHitTests extends AbstractWireSerializingTestCase<SearchHit> {
|
|||
}
|
||||
}
|
||||
|
||||
public void testToXContentEmptyFields() throws IOException {
|
||||
Map<String, DocumentField> fields = new HashMap<>();
|
||||
fields.put("foo", new DocumentField("foo", Collections.emptyList()));
|
||||
fields.put("bar", new DocumentField("bar", Collections.emptyList()));
|
||||
SearchHit hit = new SearchHit(0, "_id", null, fields, Collections.emptyMap());
|
||||
{
|
||||
BytesReference originalBytes = toShuffledXContent(hit, XContentType.JSON, ToXContent.EMPTY_PARAMS, randomBoolean());
|
||||
// checks that the fields section is completely omitted in the rendering.
|
||||
assertThat(originalBytes.utf8ToString(), not(containsString("fields")));
|
||||
final SearchHit parsed;
|
||||
try (XContentParser parser = createParser(XContentType.JSON.xContent(), originalBytes)) {
|
||||
parser.nextToken(); // jump to first START_OBJECT
|
||||
parsed = SearchHit.fromXContent(parser);
|
||||
assertEquals(XContentParser.Token.END_OBJECT, parser.currentToken());
|
||||
assertNull(parser.nextToken());
|
||||
}
|
||||
assertThat(parsed.getFields().size(), equalTo(0));
|
||||
}
|
||||
|
||||
fields = new HashMap<>();
|
||||
fields.put("foo", new DocumentField("foo", Collections.emptyList()));
|
||||
fields.put("bar", new DocumentField("bar", Collections.singletonList("value")));
|
||||
hit = new SearchHit(0, "_id", null, fields, Collections.emptyMap());
|
||||
{
|
||||
BytesReference originalBytes = toShuffledXContent(hit, XContentType.JSON, ToXContent.EMPTY_PARAMS, randomBoolean());
|
||||
final SearchHit parsed;
|
||||
try (XContentParser parser = createParser(XContentType.JSON.xContent(), originalBytes)) {
|
||||
parser.nextToken(); // jump to first START_OBJECT
|
||||
parsed = SearchHit.fromXContent(parser);
|
||||
assertEquals(XContentParser.Token.END_OBJECT, parser.currentToken());
|
||||
assertNull(parser.nextToken());
|
||||
}
|
||||
assertThat(parsed.getFields().size(), equalTo(1));
|
||||
assertThat(parsed.getFields().get("bar").getValues(), equalTo( Collections.singletonList("value")));
|
||||
}
|
||||
|
||||
Map<String, DocumentField> metadata = new HashMap<>();
|
||||
metadata.put("_routing", new DocumentField("_routing", Collections.emptyList()));
|
||||
hit = new SearchHit(0, "_id", null, fields, Collections.emptyMap());
|
||||
{
|
||||
BytesReference originalBytes = toShuffledXContent(hit, XContentType.JSON, ToXContent.EMPTY_PARAMS, randomBoolean());
|
||||
final SearchHit parsed;
|
||||
try (XContentParser parser = createParser(XContentType.JSON.xContent(), originalBytes)) {
|
||||
parser.nextToken(); // jump to first START_OBJECT
|
||||
parsed = SearchHit.fromXContent(parser);
|
||||
assertEquals(XContentParser.Token.END_OBJECT, parser.currentToken());
|
||||
assertNull(parser.nextToken());
|
||||
}
|
||||
assertThat(parsed.getFields().size(), equalTo(1));
|
||||
assertThat(parsed.getFields().get("bar").getValues(), equalTo( Collections.singletonList("value")));
|
||||
assertNull(parsed.getFields().get("_routing"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static Explanation createExplanation(int depth) {
|
||||
String description = randomAlphaOfLengthBetween(5, 20);
|
||||
float value = randomFloat();
|
||||
|
|
Loading…
Reference in New Issue