diff options
author | olcbean <olcbean@yahoo.com> | 2017-06-29 11:35:28 +0200 |
---|---|---|
committer | Christoph Büscher <christoph@elastic.co> | 2017-06-29 11:35:28 +0200 |
commit | 3518e313b81564d2868c834111d716997dd86033 (patch) | |
tree | 1a33138bf135ee90a97dd7997334f8e6d1e316d2 /core/src/main | |
parent | da59c178e2cd39ac141c8e738ad692b94813eecd (diff) |
Unify the result interfaces from get and search in Java client (#25361)
As GetField and SearchHitField have the same members, they have been unified into
DocumentField.
Closes #16440
Diffstat (limited to 'core/src/main')
13 files changed, 128 insertions, 232 deletions
diff --git a/core/src/main/java/org/elasticsearch/action/get/GetResponse.java b/core/src/main/java/org/elasticsearch/action/get/GetResponse.java index 156005fab2..9ee59cf70d 100644 --- a/core/src/main/java/org/elasticsearch/action/get/GetResponse.java +++ b/core/src/main/java/org/elasticsearch/action/get/GetResponse.java @@ -24,12 +24,12 @@ import org.elasticsearch.action.ActionResponse; import org.elasticsearch.common.ParsingException; import org.elasticsearch.common.Strings; import org.elasticsearch.common.bytes.BytesReference; +import org.elasticsearch.common.document.DocumentField; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.xcontent.ToXContentObject; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentParser; -import org.elasticsearch.index.get.GetField; import org.elasticsearch.index.get.GetResult; import java.io.IOException; @@ -44,7 +44,7 @@ import java.util.Objects; * @see GetRequest * @see org.elasticsearch.client.Client#get(GetRequest) */ -public class GetResponse extends ActionResponse implements Iterable<GetField>, ToXContentObject { +public class GetResponse extends ActionResponse implements Iterable<DocumentField>, ToXContentObject { GetResult getResult; @@ -138,11 +138,11 @@ public class GetResponse extends ActionResponse implements Iterable<GetField>, T return getResult.getSource(); } - public Map<String, GetField> getFields() { + public Map<String, DocumentField> getFields() { return getResult.getFields(); } - public GetField getField(String name) { + public DocumentField getField(String name) { return getResult.field(name); } @@ -151,7 +151,7 @@ public class GetResponse extends ActionResponse implements Iterable<GetField>, T */ @Deprecated @Override - public Iterator<GetField> iterator() { + public Iterator<DocumentField> iterator() { return getResult.iterator(); } diff --git a/core/src/main/java/org/elasticsearch/action/update/UpdateHelper.java b/core/src/main/java/org/elasticsearch/action/update/UpdateHelper.java index fb508612f5..fbf005415d 100644 --- a/core/src/main/java/org/elasticsearch/action/update/UpdateHelper.java +++ b/core/src/main/java/org/elasticsearch/action/update/UpdateHelper.java @@ -29,6 +29,7 @@ import org.elasticsearch.common.Nullable; import org.elasticsearch.common.bytes.BytesReference; import org.elasticsearch.common.collect.Tuple; import org.elasticsearch.common.component.AbstractComponent; +import org.elasticsearch.common.document.DocumentField; import org.elasticsearch.common.io.stream.BytesStreamOutput; import org.elasticsearch.common.io.stream.Streamable; import org.elasticsearch.common.settings.Settings; @@ -38,7 +39,6 @@ import org.elasticsearch.common.xcontent.XContentType; import org.elasticsearch.index.VersionType; import org.elasticsearch.index.engine.DocumentMissingException; import org.elasticsearch.index.engine.DocumentSourceMissingException; -import org.elasticsearch.index.get.GetField; import org.elasticsearch.index.get.GetResult; import org.elasticsearch.index.mapper.ParentFieldMapper; import org.elasticsearch.index.mapper.RoutingFieldMapper; @@ -324,7 +324,7 @@ public class UpdateHelper extends AbstractComponent { SourceLookup sourceLookup = new SourceLookup(); sourceLookup.setSource(source); boolean sourceRequested = false; - Map<String, GetField> fields = null; + Map<String, DocumentField> fields = null; if (request.fields() != null && request.fields().length > 0) { for (String field : request.fields()) { if (field.equals("_source")) { @@ -336,12 +336,12 @@ public class UpdateHelper extends AbstractComponent { if (fields == null) { fields = new HashMap<>(2); } - GetField getField = fields.get(field); - if (getField == null) { - getField = new GetField(field, new ArrayList<>(2)); - fields.put(field, getField); + DocumentField documentField = fields.get(field); + if (documentField == null) { + documentField = new DocumentField(field, new ArrayList<>(2)); + fields.put(field, documentField); } - getField.getValues().add(value); + documentField.getValues().add(value); } } } diff --git a/core/src/main/java/org/elasticsearch/index/get/GetField.java b/core/src/main/java/org/elasticsearch/common/document/DocumentField.java index 928988e3d3..e1cbec8b47 100644 --- a/core/src/main/java/org/elasticsearch/index/get/GetField.java +++ b/core/src/main/java/org/elasticsearch/common/document/DocumentField.java @@ -17,7 +17,7 @@ * under the License. */ -package org.elasticsearch.index.get; +package org.elasticsearch.common.document; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; @@ -25,7 +25,9 @@ import org.elasticsearch.common.io.stream.Streamable; import org.elasticsearch.common.xcontent.ToXContent; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentParser; +import org.elasticsearch.index.get.GetResult; import org.elasticsearch.index.mapper.MapperService; +import org.elasticsearch.search.SearchHit; import java.io.IOException; import java.util.ArrayList; @@ -36,34 +38,52 @@ import java.util.Objects; import static org.elasticsearch.common.xcontent.XContentParserUtils.ensureExpectedToken; import static org.elasticsearch.common.xcontent.XContentParserUtils.parseStoredFieldsValue; -public class GetField implements Streamable, ToXContent, Iterable<Object> { +/** + * A single field name and values part of {@link SearchHit} and {@link GetResult}. + * + * @see SearchHit + * @see GetResult + */ +public class DocumentField implements Streamable, ToXContent, Iterable<Object> { private String name; private List<Object> values; - private GetField() { + private DocumentField() { } - public GetField(String name, List<Object> values) { + public DocumentField(String name, List<Object> values) { this.name = Objects.requireNonNull(name, "name must not be null"); this.values = Objects.requireNonNull(values, "values must not be null"); } + /** + * The name of the field. + */ public String getName() { return name; } - public Object getValue() { - if (values != null && !values.isEmpty()) { - return values.get(0); + /** + * The first value of the hit. + */ + public <V> V getValue() { + if (values == null || values.isEmpty()) { + return null; } - return null; + return (V)values.get(0); } + /** + * The field values. + */ public List<Object> getValues() { return values; } + /** + * @return The field is a metadata field + */ public boolean isMetadataField() { return MapperService.isMetadataField(name); } @@ -73,8 +93,8 @@ public class GetField implements Streamable, ToXContent, Iterable<Object> { return values.iterator(); } - public static GetField readGetField(StreamInput in) throws IOException { - GetField result = new GetField(); + public static DocumentField readDocumentField(StreamInput in) throws IOException { + DocumentField result = new DocumentField(); result.readFrom(in); return result; } @@ -102,25 +122,26 @@ public class GetField implements Streamable, ToXContent, Iterable<Object> { public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { builder.startArray(name); for (Object value : values) { - //this call doesn't really need to support writing any kind of object. - //Stored fields values are converted using MappedFieldType#valueForDisplay. - //As a result they can either be Strings, Numbers, Booleans, or BytesReference, that's all. + // this call doesn't really need to support writing any kind of object. + // Stored fields values are converted using MappedFieldType#valueForDisplay. + // As a result they can either be Strings, Numbers, Booleans, or BytesReference, that's + // all. builder.value(value); } builder.endArray(); return builder; } - public static GetField fromXContent(XContentParser parser) throws IOException { + public static DocumentField fromXContent(XContentParser parser) throws IOException { ensureExpectedToken(XContentParser.Token.FIELD_NAME, parser.currentToken(), parser::getTokenLocation); String fieldName = parser.currentName(); XContentParser.Token token = parser.nextToken(); ensureExpectedToken(XContentParser.Token.START_ARRAY, token, parser::getTokenLocation); List<Object> values = new ArrayList<>(); - while((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) { + while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) { values.add(parseStoredFieldsValue(parser)); } - return new GetField(fieldName, values); + return new DocumentField(fieldName, values); } @Override @@ -131,9 +152,8 @@ public class GetField implements Streamable, ToXContent, Iterable<Object> { if (o == null || getClass() != o.getClass()) { return false; } - GetField objects = (GetField) o; - return Objects.equals(name, objects.name) && - Objects.equals(values, objects.values); + DocumentField objects = (DocumentField) o; + return Objects.equals(name, objects.name) && Objects.equals(values, objects.values); } @Override @@ -143,9 +163,9 @@ public class GetField implements Streamable, ToXContent, Iterable<Object> { @Override public String toString() { - return "GetField{" + + return "DocumentField{" + "name='" + name + '\'' + ", values=" + values + '}'; } -} +}
\ No newline at end of file diff --git a/core/src/main/java/org/elasticsearch/index/get/GetResult.java b/core/src/main/java/org/elasticsearch/index/get/GetResult.java index 6569902cef..a47bb8be89 100644 --- a/core/src/main/java/org/elasticsearch/index/get/GetResult.java +++ b/core/src/main/java/org/elasticsearch/index/get/GetResult.java @@ -20,9 +20,9 @@ package org.elasticsearch.index.get; import org.elasticsearch.ElasticsearchParseException; -import org.elasticsearch.common.ParsingException; import org.elasticsearch.common.bytes.BytesReference; import org.elasticsearch.common.compress.CompressorFactory; +import org.elasticsearch.common.document.DocumentField; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.io.stream.Streamable; @@ -44,9 +44,8 @@ import java.util.Objects; import static java.util.Collections.emptyMap; import static org.elasticsearch.common.xcontent.XContentParserUtils.ensureExpectedToken; -import static org.elasticsearch.index.get.GetField.readGetField; -public class GetResult implements Streamable, Iterable<GetField>, ToXContentObject { +public class GetResult implements Streamable, Iterable<DocumentField>, ToXContentObject { public static final String _INDEX = "_index"; public static final String _TYPE = "_type"; @@ -60,7 +59,7 @@ public class GetResult implements Streamable, Iterable<GetField>, ToXContentObje private String id; private long version; private boolean exists; - private Map<String, GetField> fields; + private Map<String, DocumentField> fields; private Map<String, Object> sourceAsMap; private BytesReference source; private byte[] sourceAsBytes; @@ -69,7 +68,7 @@ public class GetResult implements Streamable, Iterable<GetField>, ToXContentObje } public GetResult(String index, String type, String id, long version, boolean exists, BytesReference source, - Map<String, GetField> fields) { + Map<String, DocumentField> fields) { this.index = index; this.type = type; this.id = id; @@ -196,16 +195,16 @@ public class GetResult implements Streamable, Iterable<GetField>, ToXContentObje return sourceAsMap(); } - public Map<String, GetField> getFields() { + public Map<String, DocumentField> getFields() { return fields; } - public GetField field(String name) { + public DocumentField field(String name) { return fields.get(name); } @Override - public Iterator<GetField> iterator() { + public Iterator<DocumentField> iterator() { if (fields == null) { return Collections.emptyIterator(); } @@ -213,10 +212,10 @@ public class GetResult implements Streamable, Iterable<GetField>, ToXContentObje } public XContentBuilder toXContentEmbedded(XContentBuilder builder, Params params) throws IOException { - List<GetField> metaFields = new ArrayList<>(); - List<GetField> otherFields = new ArrayList<>(); + List<DocumentField> metaFields = new ArrayList<>(); + List<DocumentField> otherFields = new ArrayList<>(); if (fields != null && !fields.isEmpty()) { - for (GetField field : fields.values()) { + for (DocumentField field : fields.values()) { if (field.getValues().isEmpty()) { continue; } @@ -228,8 +227,9 @@ public class GetResult implements Streamable, Iterable<GetField>, ToXContentObje } } - for (GetField field : metaFields) { - builder.field(field.getName(), field.getValue()); + for (DocumentField field : metaFields) { + Object value = field.getValue(); + builder.field(field.getName(), value); } builder.field(FOUND, exists); @@ -240,7 +240,7 @@ public class GetResult implements Streamable, Iterable<GetField>, ToXContentObje if (!otherFields.isEmpty()) { builder.startObject(FIELDS); - for (GetField field : otherFields) { + for (DocumentField field : otherFields) { field.toXContent(builder, params); } builder.endObject(); @@ -275,7 +275,7 @@ public class GetResult implements Streamable, Iterable<GetField>, ToXContentObje long version = -1; Boolean found = null; BytesReference source = null; - Map<String, GetField> fields = new HashMap<>(); + Map<String, DocumentField> fields = new HashMap<>(); while((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) { if (token == XContentParser.Token.FIELD_NAME) { currentFieldName = parser.currentName(); @@ -291,7 +291,7 @@ public class GetResult implements Streamable, Iterable<GetField>, ToXContentObje } else if (FOUND.equals(currentFieldName)) { found = parser.booleanValue(); } else { - fields.put(currentFieldName, new GetField(currentFieldName, Collections.singletonList(parser.objectText()))); + fields.put(currentFieldName, new DocumentField(currentFieldName, Collections.singletonList(parser.objectText()))); } } else if (token == XContentParser.Token.START_OBJECT) { if (SourceFieldMapper.NAME.equals(currentFieldName)) { @@ -303,7 +303,7 @@ public class GetResult implements Streamable, Iterable<GetField>, ToXContentObje } } else if (FIELDS.equals(currentFieldName)) { while(parser.nextToken() != XContentParser.Token.END_OBJECT) { - GetField getField = GetField.fromXContent(parser); + DocumentField getField = DocumentField.fromXContent(parser); fields.put(getField.getName(), getField); } } else { @@ -347,7 +347,7 @@ public class GetResult implements Streamable, Iterable<GetField>, ToXContentObje } else { fields = new HashMap<>(size); for (int i = 0; i < size; i++) { - GetField field = readGetField(in); + DocumentField field = DocumentField.readDocumentField(in); fields.put(field.getName(), field); } } @@ -367,7 +367,7 @@ public class GetResult implements Streamable, Iterable<GetField>, ToXContentObje out.writeVInt(0); } else { out.writeVInt(fields.size()); - for (GetField field : fields.values()) { + for (DocumentField field : fields.values()) { field.writeTo(out); } } diff --git a/core/src/main/java/org/elasticsearch/index/get/ShardGetService.java b/core/src/main/java/org/elasticsearch/index/get/ShardGetService.java index 15e6e23428..0aeb4f3f19 100644 --- a/core/src/main/java/org/elasticsearch/index/get/ShardGetService.java +++ b/core/src/main/java/org/elasticsearch/index/get/ShardGetService.java @@ -24,6 +24,7 @@ import org.elasticsearch.ElasticsearchException; import org.elasticsearch.common.Nullable; import org.elasticsearch.common.bytes.BytesReference; import org.elasticsearch.common.collect.Tuple; +import org.elasticsearch.common.document.DocumentField; import org.elasticsearch.common.lucene.uid.VersionsAndSeqNoResolver.DocIdAndVersion; import org.elasticsearch.common.metrics.CounterMetric; import org.elasticsearch.common.metrics.MeanMetric; @@ -173,7 +174,7 @@ public final class ShardGetService extends AbstractIndexShardComponent { } private GetResult innerGetLoadFromStoredFields(String type, String id, String[] gFields, FetchSourceContext fetchSourceContext, Engine.GetResult get, MapperService mapperService) { - Map<String, GetField> fields = null; + Map<String, DocumentField> fields = null; BytesReference source = null; DocIdAndVersion docIdAndVersion = get.docIdAndVersion(); FieldsVisitor fieldVisitor = buildFieldsVisitors(gFields, fetchSourceContext); @@ -189,7 +190,7 @@ public final class ShardGetService extends AbstractIndexShardComponent { fieldVisitor.postProcess(mapperService); fields = new HashMap<>(fieldVisitor.fields().size()); for (Map.Entry<String, List<Object>> entry : fieldVisitor.fields().entrySet()) { - fields.put(entry.getKey(), new GetField(entry.getKey(), entry.getValue())); + fields.put(entry.getKey(), new DocumentField(entry.getKey(), entry.getValue())); } } } @@ -200,7 +201,7 @@ public final class ShardGetService extends AbstractIndexShardComponent { if (fields == null) { fields = new HashMap<>(1); } - fields.put(ParentFieldMapper.NAME, new GetField(ParentFieldMapper.NAME, Collections.singletonList(parentId))); + fields.put(ParentFieldMapper.NAME, new DocumentField(ParentFieldMapper.NAME, Collections.singletonList(parentId))); } if (gFields != null && gFields.length > 0) { diff --git a/core/src/main/java/org/elasticsearch/index/reindex/ClientScrollableHitSource.java b/core/src/main/java/org/elasticsearch/index/reindex/ClientScrollableHitSource.java index 2f6775a1ea..5124201997 100644 --- a/core/src/main/java/org/elasticsearch/index/reindex/ClientScrollableHitSource.java +++ b/core/src/main/java/org/elasticsearch/index/reindex/ClientScrollableHitSource.java @@ -34,6 +34,7 @@ import org.elasticsearch.action.search.ShardSearchFailure; import org.elasticsearch.client.Client; import org.elasticsearch.client.ParentTaskAssigningClient; import org.elasticsearch.common.bytes.BytesReference; +import org.elasticsearch.common.document.DocumentField; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.util.concurrent.AbstractRunnable; import org.elasticsearch.common.util.concurrent.EsRejectedExecutionException; @@ -42,7 +43,6 @@ import org.elasticsearch.common.xcontent.XContentType; import org.elasticsearch.index.mapper.ParentFieldMapper; import org.elasticsearch.index.mapper.RoutingFieldMapper; import org.elasticsearch.search.SearchHit; -import org.elasticsearch.search.SearchHitField; import org.elasticsearch.threadpool.ThreadPool; import java.util.ArrayList; @@ -254,7 +254,7 @@ public class ClientScrollableHitSource extends ScrollableHitSource { } private <T> T fieldValue(String fieldName) { - SearchHitField field = delegate.field(fieldName); + DocumentField field = delegate.field(fieldName); return field == null ? null : field.getValue(); } } diff --git a/core/src/main/java/org/elasticsearch/index/termvectors/TermVectorsService.java b/core/src/main/java/org/elasticsearch/index/termvectors/TermVectorsService.java index 8291e76c2a..495f1dc4bd 100644 --- a/core/src/main/java/org/elasticsearch/index/termvectors/TermVectorsService.java +++ b/core/src/main/java/org/elasticsearch/index/termvectors/TermVectorsService.java @@ -34,12 +34,12 @@ import org.elasticsearch.action.termvectors.TermVectorsResponse; import org.elasticsearch.common.Nullable; import org.elasticsearch.common.Strings; import org.elasticsearch.common.bytes.BytesReference; +import org.elasticsearch.common.document.DocumentField; import org.elasticsearch.common.lucene.uid.VersionsAndSeqNoResolver.DocIdAndVersion; import org.elasticsearch.common.xcontent.XContentHelper; import org.elasticsearch.common.xcontent.XContentType; import org.elasticsearch.common.xcontent.support.XContentMapValues; import org.elasticsearch.index.engine.Engine; -import org.elasticsearch.index.get.GetField; import org.elasticsearch.index.get.GetResult; import org.elasticsearch.index.mapper.DocumentMapperForType; import org.elasticsearch.index.mapper.KeywordFieldMapper; @@ -235,9 +235,9 @@ public class TermVectorsService { return selectedFields; } - private static Fields generateTermVectors(IndexShard indexShard, Map<String, Object> source, Collection<GetField> getFields, boolean withOffsets, @Nullable Map<String, String> perFieldAnalyzer, Set<String> fields) throws IOException { + private static Fields generateTermVectors(IndexShard indexShard, Map<String, Object> source, Collection<DocumentField> getFields, boolean withOffsets, @Nullable Map<String, String> perFieldAnalyzer, Set<String> fields) throws IOException { Map<String, Collection<Object>> values = new HashMap<>(); - for (GetField getField : getFields) { + for (DocumentField getField : getFields) { String field = getField.getName(); if (fields.contains(field)) { // some fields are returned even when not asked for, eg. _timestamp values.put(field, getField.getValues()); @@ -279,7 +279,7 @@ public class TermVectorsService { // select the right fields and generate term vectors ParseContext.Document doc = parsedDocument.rootDoc(); Set<String> seenFields = new HashSet<>(); - Collection<GetField> getFields = new HashSet<>(); + Collection<DocumentField> documentFields = new HashSet<>(); for (IndexableField field : doc.getFields()) { MappedFieldType fieldType = indexShard.mapperService().fullName(field.name()); if (!isValidField(fieldType)) { @@ -295,10 +295,10 @@ public class TermVectorsService { seenFields.add(field.name()); } String[] values = doc.getValues(field.name()); - getFields.add(new GetField(field.name(), Arrays.asList((Object[]) values))); + documentFields.add(new DocumentField(field.name(), Arrays.asList((Object[]) values))); } return generateTermVectors(indexShard, XContentHelper.convertToMap(parsedDocument.source(), true, request.xContentType()).v2(), - getFields, request.offsets(), request.perFieldAnalyzer(), seenFields); + documentFields, request.offsets(), request.perFieldAnalyzer(), seenFields); } private static ParsedDocument parseDocument(IndexShard indexShard, String index, String type, BytesReference doc, diff --git a/core/src/main/java/org/elasticsearch/search/SearchHit.java b/core/src/main/java/org/elasticsearch/search/SearchHit.java index 81cba7d8db..21a77bfd4b 100644 --- a/core/src/main/java/org/elasticsearch/search/SearchHit.java +++ b/core/src/main/java/org/elasticsearch/search/SearchHit.java @@ -28,6 +28,7 @@ import org.elasticsearch.common.ParsingException; import org.elasticsearch.common.Strings; import org.elasticsearch.common.bytes.BytesReference; import org.elasticsearch.common.compress.CompressorFactory; +import org.elasticsearch.common.document.DocumentField; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.io.stream.Streamable; @@ -75,7 +76,7 @@ import static org.elasticsearch.search.fetch.subphase.highlight.HighlightField.r * * @see SearchHits */ -public final class SearchHit implements Streamable, ToXContentObject, Iterable<SearchHitField> { +public final class SearchHit implements Streamable, ToXContentObject, Iterable<DocumentField> { private transient int docId; @@ -91,7 +92,7 @@ public final class SearchHit implements Streamable, ToXContentObject, Iterable<S private BytesReference source; - private Map<String, SearchHitField> fields = emptyMap(); + private Map<String, DocumentField> fields = emptyMap(); private Map<String, HighlightField> highlightFields = null; @@ -118,11 +119,11 @@ public final class SearchHit implements Streamable, ToXContentObject, Iterable<S this(docId, null, null, null); } - public SearchHit(int docId, String id, Text type, Map<String, SearchHitField> fields) { + public SearchHit(int docId, String id, Text type, Map<String, DocumentField> fields) { this(docId, id, type, null, fields); } - public SearchHit(int nestedTopDocId, String id, Text type, NestedIdentity nestedIdentity, Map<String, SearchHitField> fields) { + public SearchHit(int nestedTopDocId, String id, Text type, NestedIdentity nestedIdentity, Map<String, DocumentField> fields) { this.docId = nestedTopDocId; if (id != null) { this.id = new Text(id); @@ -252,14 +253,14 @@ public final class SearchHit implements Streamable, ToXContentObject, Iterable<S } @Override - public Iterator<SearchHitField> iterator() { + public Iterator<DocumentField> iterator() { return fields.values().iterator(); } /** * The hit field matching the given field name. */ - public SearchHitField field(String fieldName) { + public DocumentField field(String fieldName) { return getFields().get(fieldName); } @@ -267,16 +268,16 @@ public final class SearchHit implements Streamable, ToXContentObject, Iterable<S * A map of hit fields (from field name to hit fields) if additional fields * were required to be loaded. */ - public Map<String, SearchHitField> getFields() { + public Map<String, DocumentField> getFields() { return fields == null ? emptyMap() : fields; } // returns the fields without handling null cases - public Map<String, SearchHitField> fieldsOrNull() { + public Map<String, DocumentField> fieldsOrNull() { return fields; } - public void fields(Map<String, SearchHitField> fields) { + public void fields(Map<String, DocumentField> fields) { this.fields = fields; } @@ -382,10 +383,10 @@ public final class SearchHit implements Streamable, ToXContentObject, Iterable<S // public because we render hit as part of completion suggestion option public XContentBuilder toInnerXContent(XContentBuilder builder, Params params) throws IOException { - List<SearchHitField> metaFields = new ArrayList<>(); - List<SearchHitField> otherFields = new ArrayList<>(); + List<DocumentField> metaFields = new ArrayList<>(); + List<DocumentField> otherFields = new ArrayList<>(); if (fields != null && !fields.isEmpty()) { - for (SearchHitField field : fields.values()) { + for (DocumentField field : fields.values()) { if (field.getValues().isEmpty()) { continue; } @@ -424,7 +425,7 @@ public final class SearchHit implements Streamable, ToXContentObject, Iterable<S } else { builder.field(Fields._SCORE, score); } - for (SearchHitField field : metaFields) { + for (DocumentField field : metaFields) { Object value = field.getValue(); builder.field(field.getName(), value); } @@ -433,7 +434,7 @@ public final class SearchHit implements Streamable, ToXContentObject, Iterable<S } if (!otherFields.isEmpty()) { builder.startObject(Fields.FIELDS); - for (SearchHitField field : otherFields) { + for (DocumentField field : otherFields) { builder.startArray(field.getName()); for (Object value : field.getValues()) { builder.value(value); @@ -509,7 +510,7 @@ public final class SearchHit implements Streamable, ToXContentObject, Iterable<S parser.declareObject((map, value) -> map.put(Fields.HIGHLIGHT, value), (p, c) -> parseHighlightFields(p), new ParseField(Fields.HIGHLIGHT)); parser.declareObject((map, value) -> { - Map<String, SearchHitField> fieldMap = get(Fields.FIELDS, map, new HashMap<String, SearchHitField>()); + Map<String, DocumentField> fieldMap = get(Fields.FIELDS, map, new HashMap<String, DocumentField>()); fieldMap.putAll(value); map.put(Fields.FIELDS, fieldMap); }, (p, c) -> parseFields(p), new ParseField(Fields.FIELDS)); @@ -528,7 +529,7 @@ public final class SearchHit implements Streamable, ToXContentObject, Iterable<S String id = get(Fields._ID, values, null); Text type = get(Fields._TYPE, values, null); NestedIdentity nestedIdentity = get(NestedIdentity._NESTED, values, null); - Map<String, SearchHitField> fields = get(Fields.FIELDS, values, null); + Map<String, DocumentField> fields = get(Fields.FIELDS, values, null); SearchHit searchHit = new SearchHit(-1, id, type, nestedIdentity, fields); searchHit.index = get(Fields._INDEX, values, null); @@ -585,20 +586,20 @@ public final class SearchHit implements Streamable, ToXContentObject, Iterable<S && metadatafield.equals(Fields._TYPE) == false) { parser.declareField((map, field) -> { @SuppressWarnings("unchecked") - Map<String, SearchHitField> fieldMap = (Map<String, SearchHitField>) map.computeIfAbsent(Fields.FIELDS, - v -> new HashMap<String, SearchHitField>()); + Map<String, DocumentField> fieldMap = (Map<String, DocumentField>) map.computeIfAbsent(Fields.FIELDS, + v -> new HashMap<String, DocumentField>()); fieldMap.put(field.getName(), field); }, (p, c) -> { List<Object> values = new ArrayList<>(); values.add(parseStoredFieldsValue(p)); - return new SearchHitField(metadatafield, values); + return new DocumentField(metadatafield, values); }, new ParseField(metadatafield), ValueType.VALUE); } } } - private static Map<String, SearchHitField> parseFields(XContentParser parser) throws IOException { - Map<String, SearchHitField> fields = new HashMap<>(); + private static Map<String, DocumentField> parseFields(XContentParser parser) throws IOException { + Map<String, DocumentField> fields = new HashMap<>(); while ((parser.nextToken()) != XContentParser.Token.END_OBJECT) { String fieldName = parser.currentName(); ensureExpectedToken(XContentParser.Token.START_ARRAY, parser.nextToken(), parser::getTokenLocation); @@ -606,7 +607,7 @@ public final class SearchHit implements Streamable, ToXContentObject, Iterable<S while ((parser.nextToken()) != XContentParser.Token.END_ARRAY) { values.add(parseStoredFieldsValue(parser)); } - fields.put(fieldName, new SearchHitField(fieldName, values)); + fields.put(fieldName, new DocumentField(fieldName, values)); } return fields; } @@ -704,12 +705,12 @@ public final class SearchHit implements Streamable, ToXContentObject, Iterable<S if (size == 0) { fields = emptyMap(); } else if (size == 1) { - SearchHitField hitField = SearchHitField.readSearchHitField(in); + DocumentField hitField = DocumentField.readDocumentField(in); fields = singletonMap(hitField.getName(), hitField); } else { - Map<String, SearchHitField> fields = new HashMap<>(); + Map<String, DocumentField> fields = new HashMap<>(); for (int i = 0; i < size; i++) { - SearchHitField hitField = SearchHitField.readSearchHitField(in); + DocumentField hitField = DocumentField.readDocumentField(in); fields.put(hitField.getName(), hitField); } this.fields = unmodifiableMap(fields); @@ -770,7 +771,7 @@ public final class SearchHit implements Streamable, ToXContentObject, Iterable<S out.writeVInt(0); } else { out.writeVInt(fields.size()); - for (SearchHitField hitField : getFields().values()) { + for (DocumentField hitField : getFields().values()) { hitField.writeTo(out); } } diff --git a/core/src/main/java/org/elasticsearch/search/SearchHitField.java b/core/src/main/java/org/elasticsearch/search/SearchHitField.java deleted file mode 100644 index fbb211b90d..0000000000 --- a/core/src/main/java/org/elasticsearch/search/SearchHitField.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * 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.search; - -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import org.elasticsearch.common.io.stream.Streamable; -import org.elasticsearch.index.mapper.MapperService; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.Objects; - -/** - * A single field name and values part of a {@link SearchHit}. - * - * @see SearchHit - */ -public final class SearchHitField implements Streamable, Iterable<Object> { - - private String name; - private List<Object> values; - - private SearchHitField() { - } - - public SearchHitField(String name, List<Object> values) { - this.name = name; - this.values = values; - } - - /** - * The name of the field. - */ - public String getName() { - return name; - } - - /** - * The first value of the hit. - */ - public <V> V getValue() { - if (values == null || values.isEmpty()) { - return null; - } - return (V)values.get(0); - } - - /** - * The field values. - */ - public List<Object> getValues() { - return values; - } - - /** - * @return The field is a metadata field - */ - public boolean isMetadataField() { - return MapperService.isMetadataField(name); - } - - @Override - public Iterator<Object> iterator() { - return values.iterator(); - } - - public static SearchHitField readSearchHitField(StreamInput in) throws IOException { - SearchHitField result = new SearchHitField(); - result.readFrom(in); - return result; - } - - @Override - public void readFrom(StreamInput in) throws IOException { - name = in.readString(); - int size = in.readVInt(); - values = new ArrayList<>(size); - for (int i = 0; i < size; i++) { - values.add(in.readGenericValue()); - } - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - out.writeString(name); - out.writeVInt(values.size()); - for (Object value : values) { - out.writeGenericValue(value); - } - } - - @Override - public boolean equals(Object obj) { - if (obj == null || getClass() != obj.getClass()) { - return false; - } - SearchHitField other = (SearchHitField) obj; - return Objects.equals(name, other.name) - && Objects.equals(values, other.values); - } - - @Override - public int hashCode() { - return Objects.hash(name, values); - } -} diff --git a/core/src/main/java/org/elasticsearch/search/fetch/FetchPhase.java b/core/src/main/java/org/elasticsearch/search/fetch/FetchPhase.java index e5bfcfa6df..e28bd505d3 100644 --- a/core/src/main/java/org/elasticsearch/search/fetch/FetchPhase.java +++ b/core/src/main/java/org/elasticsearch/search/fetch/FetchPhase.java @@ -29,6 +29,7 @@ import org.apache.lucene.util.BitSet; import org.elasticsearch.ExceptionsHelper; import org.elasticsearch.common.bytes.BytesReference; import org.elasticsearch.common.collect.Tuple; +import org.elasticsearch.common.document.DocumentField; import org.elasticsearch.common.lucene.search.Queries; import org.elasticsearch.common.regex.Regex; import org.elasticsearch.common.text.Text; @@ -42,11 +43,10 @@ import org.elasticsearch.index.mapper.MappedFieldType; import org.elasticsearch.index.mapper.ObjectMapper; import org.elasticsearch.index.mapper.SourceFieldMapper; import org.elasticsearch.search.SearchHit; -import org.elasticsearch.search.SearchHitField; +import org.elasticsearch.search.SearchHits; import org.elasticsearch.search.SearchPhase; import org.elasticsearch.search.fetch.subphase.FetchSourceContext; import org.elasticsearch.search.fetch.subphase.InnerHitsFetchSubPhase; -import org.elasticsearch.search.SearchHits; import org.elasticsearch.search.internal.SearchContext; import org.elasticsearch.search.lookup.SourceLookup; import org.elasticsearch.tasks.TaskCancelledException; @@ -186,11 +186,11 @@ public class FetchPhase implements SearchPhase { loadStoredFields(context, subReaderContext, fieldsVisitor, subDocId); fieldsVisitor.postProcess(context.mapperService()); - Map<String, SearchHitField> searchFields = null; + Map<String, DocumentField> searchFields = null; if (!fieldsVisitor.fields().isEmpty()) { searchFields = new HashMap<>(fieldsVisitor.fields().size()); for (Map.Entry<String, List<Object>> entry : fieldsVisitor.fields().entrySet()) { - searchFields.put(entry.getKey(), new SearchHitField(entry.getKey(), entry.getValue())); + searchFields.put(entry.getKey(), new DocumentField(entry.getKey(), entry.getValue())); } } @@ -219,7 +219,7 @@ public class FetchPhase implements SearchPhase { loadStoredFields(context, subReaderContext, rootFieldsVisitor, rootSubDocId); rootFieldsVisitor.postProcess(context.mapperService()); - Map<String, SearchHitField> searchFields = getSearchFields(context, nestedSubDocId, fieldNames, fieldNamePatterns, subReaderContext); + Map<String, DocumentField> searchFields = getSearchFields(context, nestedSubDocId, fieldNames, fieldNamePatterns, subReaderContext); DocumentMapper documentMapper = context.mapperService().documentMapper(rootFieldsVisitor.uid().type()); SourceLookup sourceLookup = context.lookup().source(); sourceLookup.setSegmentAndDocument(subReaderContext, nestedSubDocId); @@ -272,8 +272,8 @@ public class FetchPhase implements SearchPhase { return new SearchHit(nestedTopDocId, rootFieldsVisitor.uid().id(), documentMapper.typeText(), nestedIdentity, searchFields); } - private Map<String, SearchHitField> getSearchFields(SearchContext context, int nestedSubDocId, Set<String> fieldNames, List<String> fieldNamePatterns, LeafReaderContext subReaderContext) { - Map<String, SearchHitField> searchFields = null; + private Map<String, DocumentField> getSearchFields(SearchContext context, int nestedSubDocId, Set<String> fieldNames, List<String> fieldNamePatterns, LeafReaderContext subReaderContext) { + Map<String, DocumentField> searchFields = null; if (context.hasStoredFields() && !context.storedFieldsContext().fieldNames().isEmpty()) { FieldsVisitor nestedFieldsVisitor = new CustomFieldsVisitor(fieldNames == null ? Collections.emptySet() : fieldNames, fieldNamePatterns == null ? Collections.emptyList() : fieldNamePatterns, false); @@ -283,7 +283,7 @@ public class FetchPhase implements SearchPhase { if (!nestedFieldsVisitor.fields().isEmpty()) { searchFields = new HashMap<>(nestedFieldsVisitor.fields().size()); for (Map.Entry<String, List<Object>> entry : nestedFieldsVisitor.fields().entrySet()) { - searchFields.put(entry.getKey(), new SearchHitField(entry.getKey(), entry.getValue())); + searchFields.put(entry.getKey(), new DocumentField(entry.getKey(), entry.getValue())); } } } diff --git a/core/src/main/java/org/elasticsearch/search/fetch/subphase/DocValueFieldsFetchSubPhase.java b/core/src/main/java/org/elasticsearch/search/fetch/subphase/DocValueFieldsFetchSubPhase.java index 42cee23d39..cd0f1645ce 100644 --- a/core/src/main/java/org/elasticsearch/search/fetch/subphase/DocValueFieldsFetchSubPhase.java +++ b/core/src/main/java/org/elasticsearch/search/fetch/subphase/DocValueFieldsFetchSubPhase.java @@ -18,10 +18,10 @@ */ package org.elasticsearch.search.fetch.subphase; +import org.elasticsearch.common.document.DocumentField; import org.elasticsearch.index.fielddata.AtomicFieldData; import org.elasticsearch.index.fielddata.ScriptDocValues; import org.elasticsearch.index.mapper.MappedFieldType; -import org.elasticsearch.search.SearchHitField; import org.elasticsearch.search.fetch.FetchSubPhase; import org.elasticsearch.search.internal.SearchContext; @@ -55,9 +55,9 @@ public final class DocValueFieldsFetchSubPhase implements FetchSubPhase { if (hitContext.hit().fieldsOrNull() == null) { hitContext.hit().fields(new HashMap<>(2)); } - SearchHitField hitField = hitContext.hit().getFields().get(field); + DocumentField hitField = hitContext.hit().getFields().get(field); if (hitField == null) { - hitField = new SearchHitField(field, new ArrayList<>(2)); + hitField = new DocumentField(field, new ArrayList<>(2)); hitContext.hit().getFields().put(field, hitField); } MappedFieldType fieldType = context.mapperService().fullName(field); diff --git a/core/src/main/java/org/elasticsearch/search/fetch/subphase/ParentFieldSubFetchPhase.java b/core/src/main/java/org/elasticsearch/search/fetch/subphase/ParentFieldSubFetchPhase.java index 0ffef32e42..93fc9ccb1f 100644 --- a/core/src/main/java/org/elasticsearch/search/fetch/subphase/ParentFieldSubFetchPhase.java +++ b/core/src/main/java/org/elasticsearch/search/fetch/subphase/ParentFieldSubFetchPhase.java @@ -23,8 +23,8 @@ import org.apache.lucene.index.LeafReader; import org.apache.lucene.index.SortedDocValues; import org.apache.lucene.util.BytesRef; import org.elasticsearch.ExceptionsHelper; +import org.elasticsearch.common.document.DocumentField; import org.elasticsearch.index.mapper.ParentFieldMapper; -import org.elasticsearch.search.SearchHitField; import org.elasticsearch.search.fetch.FetchSubPhase; import org.elasticsearch.search.internal.SearchContext; @@ -51,12 +51,12 @@ public final class ParentFieldSubFetchPhase implements FetchSubPhase { return; } - Map<String, SearchHitField> fields = hitContext.hit().fieldsOrNull(); + Map<String, DocumentField> fields = hitContext.hit().fieldsOrNull(); if (fields == null) { fields = new HashMap<>(); hitContext.hit().fields(fields); } - fields.put(ParentFieldMapper.NAME, new SearchHitField(ParentFieldMapper.NAME, Collections.singletonList(parentId))); + fields.put(ParentFieldMapper.NAME, new DocumentField(ParentFieldMapper.NAME, Collections.singletonList(parentId))); } public static String getParentId(ParentFieldMapper fieldMapper, LeafReader reader, int docId) { diff --git a/core/src/main/java/org/elasticsearch/search/fetch/subphase/ScriptFieldsFetchSubPhase.java b/core/src/main/java/org/elasticsearch/search/fetch/subphase/ScriptFieldsFetchSubPhase.java index 61c1c802de..82e0725ae1 100644 --- a/core/src/main/java/org/elasticsearch/search/fetch/subphase/ScriptFieldsFetchSubPhase.java +++ b/core/src/main/java/org/elasticsearch/search/fetch/subphase/ScriptFieldsFetchSubPhase.java @@ -18,8 +18,8 @@ */ package org.elasticsearch.search.fetch.subphase; +import org.elasticsearch.common.document.DocumentField; import org.elasticsearch.script.SearchScript; -import org.elasticsearch.search.SearchHitField; import org.elasticsearch.search.fetch.FetchSubPhase; import org.elasticsearch.search.internal.SearchContext; @@ -62,7 +62,7 @@ public final class ScriptFieldsFetchSubPhase implements FetchSubPhase { hitContext.hit().fields(new HashMap<>(2)); } - SearchHitField hitField = hitContext.hit().getFields().get(scriptField.name()); + DocumentField hitField = hitContext.hit().getFields().get(scriptField.name()); if (hitField == null) { final List<Object> values; if (value instanceof Collection) { @@ -71,7 +71,7 @@ public final class ScriptFieldsFetchSubPhase implements FetchSubPhase { } else { values = Collections.singletonList(value); } - hitField = new SearchHitField(scriptField.name(), values); + hitField = new DocumentField(scriptField.name(), values); hitContext.hit().getFields().put(scriptField.name(), hitField); } } |