diff options
Diffstat (limited to 'core/src/main/java/org/elasticsearch/index')
11 files changed, 74 insertions, 28 deletions
diff --git a/core/src/main/java/org/elasticsearch/index/IndexingSlowLog.java b/core/src/main/java/org/elasticsearch/index/IndexingSlowLog.java index 8672bbc835..b1d8ac1886 100644 --- a/core/src/main/java/org/elasticsearch/index/IndexingSlowLog.java +++ b/core/src/main/java/org/elasticsearch/index/IndexingSlowLog.java @@ -190,7 +190,7 @@ public final class IndexingSlowLog implements IndexingOperationListener { return sb.toString(); } try { - String source = XContentHelper.convertToJson(doc.source(), reformat); + String source = XContentHelper.convertToJson(doc.source(), reformat, doc.getXContentType()); sb.append(", source[").append(Strings.cleanTruncate(source, maxSourceCharsToLog)).append("]"); } catch (IOException e) { sb.append(", source[_failed_to_convert_]"); diff --git a/core/src/main/java/org/elasticsearch/index/mapper/DocumentMapper.java b/core/src/main/java/org/elasticsearch/index/mapper/DocumentMapper.java index fdc45530b9..a8c74101bf 100644 --- a/core/src/main/java/org/elasticsearch/index/mapper/DocumentMapper.java +++ b/core/src/main/java/org/elasticsearch/index/mapper/DocumentMapper.java @@ -30,6 +30,7 @@ import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.text.Text; import org.elasticsearch.common.xcontent.ToXContent; import org.elasticsearch.common.xcontent.XContentBuilder; +import org.elasticsearch.common.xcontent.XContentFactory; import org.elasticsearch.common.xcontent.XContentType; import org.elasticsearch.index.IndexSettings; import org.elasticsearch.index.analysis.IndexAnalyzers; @@ -256,8 +257,9 @@ public class DocumentMapper implements ToXContent { return this.objectMappers; } + // TODO this method looks like it is only used in tests... public ParsedDocument parse(String index, String type, String id, BytesReference source) throws MapperParsingException { - return parse(SourceToParse.source(index, type, id, source)); + return parse(SourceToParse.source(index, type, id, source, XContentType.JSON)); } public ParsedDocument parse(SourceToParse source) throws MapperParsingException { diff --git a/core/src/main/java/org/elasticsearch/index/mapper/DocumentMapperParser.java b/core/src/main/java/org/elasticsearch/index/mapper/DocumentMapperParser.java index 031f139075..be25775c13 100644 --- a/core/src/main/java/org/elasticsearch/index/mapper/DocumentMapperParser.java +++ b/core/src/main/java/org/elasticsearch/index/mapper/DocumentMapperParser.java @@ -24,9 +24,9 @@ import org.elasticsearch.common.Nullable; import org.elasticsearch.common.collect.Tuple; import org.elasticsearch.common.compress.CompressedXContent; import org.elasticsearch.common.xcontent.NamedXContentRegistry; -import org.elasticsearch.common.xcontent.XContentFactory; import org.elasticsearch.common.xcontent.XContentHelper; import org.elasticsearch.common.xcontent.XContentParser; +import org.elasticsearch.common.xcontent.XContentType; import org.elasticsearch.index.IndexSettings; import org.elasticsearch.index.analysis.IndexAnalyzers; import org.elasticsearch.index.query.QueryShardContext; @@ -80,7 +80,7 @@ public class DocumentMapperParser { public DocumentMapper parse(@Nullable String type, CompressedXContent source, String defaultSource) throws MapperParsingException { Map<String, Object> mapping = null; if (source != null) { - Map<String, Object> root = XContentHelper.convertToMap(source.compressedReference(), true).v2(); + Map<String, Object> root = XContentHelper.convertToMap(source.compressedReference(), true, XContentType.JSON).v2(); Tuple<String, Map<String, Object>> t = extractMapping(type, root); type = t.v1(); mapping = t.v2(); @@ -162,7 +162,7 @@ public class DocumentMapperParser { private Tuple<String, Map<String, Object>> extractMapping(String type, String source) throws MapperParsingException { Map<String, Object> root; - try (XContentParser parser = XContentFactory.xContent(source).createParser(xContentRegistry, source)) { + try (XContentParser parser = XContentType.JSON.xContent().createParser(xContentRegistry, source)) { root = parser.mapOrdered(); } catch (Exception e) { throw new MapperParsingException("failed to parse mapping definition", e); diff --git a/core/src/main/java/org/elasticsearch/index/mapper/DocumentParser.java b/core/src/main/java/org/elasticsearch/index/mapper/DocumentParser.java index 014ff45200..97891b28aa 100644 --- a/core/src/main/java/org/elasticsearch/index/mapper/DocumentParser.java +++ b/core/src/main/java/org/elasticsearch/index/mapper/DocumentParser.java @@ -154,6 +154,7 @@ final class DocumentParser { source.routing(), context.docs(), context.sourceToParse().source(), + context.sourceToParse().getXContentType(), update ).parent(source.parent()); } diff --git a/core/src/main/java/org/elasticsearch/index/mapper/MapperService.java b/core/src/main/java/org/elasticsearch/index/mapper/MapperService.java index ee4b5fea15..41b29f3c67 100755 --- a/core/src/main/java/org/elasticsearch/index/mapper/MapperService.java +++ b/core/src/main/java/org/elasticsearch/index/mapper/MapperService.java @@ -30,6 +30,7 @@ import org.elasticsearch.Version; import org.elasticsearch.cluster.metadata.IndexMetaData; import org.elasticsearch.cluster.metadata.MappingMetaData; import org.elasticsearch.common.Nullable; +import org.elasticsearch.common.bytes.BytesReference; import org.elasticsearch.common.compress.CompressedXContent; import org.elasticsearch.common.regex.Regex; import org.elasticsearch.common.settings.Setting; @@ -37,6 +38,7 @@ import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.xcontent.NamedXContentRegistry; import org.elasticsearch.common.xcontent.XContentFactory; import org.elasticsearch.common.xcontent.XContentParser; +import org.elasticsearch.common.xcontent.XContentType; import org.elasticsearch.index.AbstractIndexComponent; import org.elasticsearch.index.IndexSettings; import org.elasticsearch.index.analysis.IndexAnalyzers; @@ -189,8 +191,11 @@ public class MapperService extends AbstractIndexComponent implements Closeable { return this.documentParser; } + /** + * Parses the mappings (formatted as JSON) into a map + */ public static Map<String, Object> parseMapping(NamedXContentRegistry xContentRegistry, String mappingSource) throws Exception { - try (XContentParser parser = XContentFactory.xContent(mappingSource).createParser(xContentRegistry, mappingSource)) { + try (XContentParser parser = XContentType.JSON.xContent().createParser(xContentRegistry, mappingSource)) { return parser.map(); } } @@ -318,7 +323,8 @@ public class MapperService extends AbstractIndexComponent implements Closeable { && mappers.containsKey(type) == false; try { - DocumentMapper documentMapper = documentParser.parse(type, entry.getValue(), applyDefault ? defaultMappingSourceOrLastStored : null); + DocumentMapper documentMapper = + documentParser.parse(type, entry.getValue(), applyDefault ? defaultMappingSourceOrLastStored : null); documentMappers.add(documentMapper); } catch (Exception e) { throw new MapperParsingException("Failed to parse mapping [{}]: {}", e, entry.getKey(), e.getMessage()); diff --git a/core/src/main/java/org/elasticsearch/index/mapper/ParsedDocument.java b/core/src/main/java/org/elasticsearch/index/mapper/ParsedDocument.java index db8bdf9df7..f7d5804be0 100644 --- a/core/src/main/java/org/elasticsearch/index/mapper/ParsedDocument.java +++ b/core/src/main/java/org/elasticsearch/index/mapper/ParsedDocument.java @@ -22,8 +22,8 @@ package org.elasticsearch.index.mapper; import org.apache.lucene.document.Field; import org.apache.lucene.util.BytesRef; import org.elasticsearch.common.bytes.BytesReference; +import org.elasticsearch.common.xcontent.XContentType; import org.elasticsearch.index.mapper.ParseContext.Document; -import org.elasticsearch.index.mapper.SeqNoFieldMapper; import java.util.List; @@ -43,6 +43,7 @@ public class ParsedDocument { private final List<Document> documents; private BytesReference source; + private XContentType xContentType; private Mapping dynamicMappingsUpdate; @@ -55,6 +56,7 @@ public class ParsedDocument { String routing, List<Document> documents, BytesReference source, + XContentType xContentType, Mapping dynamicMappingsUpdate) { this.version = version; this.seqID = seqID; @@ -65,6 +67,7 @@ public class ParsedDocument { this.documents = documents; this.source = source; this.dynamicMappingsUpdate = dynamicMappingsUpdate; + this.xContentType = xContentType; } public BytesRef uid() { @@ -105,8 +108,13 @@ public class ParsedDocument { return this.source; } - public void setSource(BytesReference source) { + public XContentType getXContentType() { + return this.xContentType; + } + + public void setSource(BytesReference source, XContentType xContentType) { this.source = source; + this.xContentType = xContentType; } public ParsedDocument parent(String parent) { diff --git a/core/src/main/java/org/elasticsearch/index/mapper/SourceFieldMapper.java b/core/src/main/java/org/elasticsearch/index/mapper/SourceFieldMapper.java index e06ec80a47..2eb2fdeaa0 100644 --- a/core/src/main/java/org/elasticsearch/index/mapper/SourceFieldMapper.java +++ b/core/src/main/java/org/elasticsearch/index/mapper/SourceFieldMapper.java @@ -241,7 +241,8 @@ public class SourceFieldMapper extends MetadataFieldMapper { if (filter != null) { // we don't update the context source if we filter, we want to keep it as is... - Tuple<XContentType, Map<String, Object>> mapTuple = XContentHelper.convertToMap(source, true); + Tuple<XContentType, Map<String, Object>> mapTuple = + XContentHelper.convertToMap(source, true, context.sourceToParse().getXContentType()); Map<String, Object> filteredSource = filter.apply(mapTuple.v2()); BytesStreamOutput bStream = new BytesStreamOutput(); XContentType contentType = mapTuple.v1(); diff --git a/core/src/main/java/org/elasticsearch/index/mapper/SourceToParse.java b/core/src/main/java/org/elasticsearch/index/mapper/SourceToParse.java index 0cafc50bbe..a8a983ecde 100644 --- a/core/src/main/java/org/elasticsearch/index/mapper/SourceToParse.java +++ b/core/src/main/java/org/elasticsearch/index/mapper/SourceToParse.java @@ -23,15 +23,18 @@ import java.util.Objects; import org.elasticsearch.common.bytes.BytesArray; import org.elasticsearch.common.bytes.BytesReference; +import org.elasticsearch.common.xcontent.XContentFactory; +import org.elasticsearch.common.xcontent.XContentType; public class SourceToParse { - public static SourceToParse source(String index, String type, String id, BytesReference source) { - return source(Origin.PRIMARY, index, type, id, source); + public static SourceToParse source(String index, String type, String id, BytesReference source, XContentType contentType) { + return source(Origin.PRIMARY, index, type, id, source, contentType); } - public static SourceToParse source(Origin origin, String index, String type, String id, BytesReference source) { - return new SourceToParse(origin, index, type, id, source); + public static SourceToParse source(Origin origin, String index, String type, String id, BytesReference source, + XContentType contentType) { + return new SourceToParse(origin, index, type, id, source, contentType); } private final Origin origin; @@ -48,14 +51,17 @@ public class SourceToParse { private String parentId; - private SourceToParse(Origin origin, String index, String type, String id, BytesReference source) { + private XContentType xContentType; + + private SourceToParse(Origin origin, String index, String type, String id, BytesReference source, XContentType xContentType) { this.origin = Objects.requireNonNull(origin); this.index = Objects.requireNonNull(index); this.type = Objects.requireNonNull(type); this.id = Objects.requireNonNull(id); // we always convert back to byte array, since we store it and Field only supports bytes.. // so, we might as well do it here, and improve the performance of working with direct byte arrays - this.source = new BytesArray(source.toBytesRef()); + this.source = new BytesArray(Objects.requireNonNull(source).toBytesRef()); + this.xContentType = Objects.requireNonNull(xContentType); } public Origin origin() { @@ -91,6 +97,10 @@ public class SourceToParse { return this.routing; } + public XContentType getXContentType() { + return this.xContentType; + } + public SourceToParse routing(String routing) { this.routing = routing; return this; diff --git a/core/src/main/java/org/elasticsearch/index/query/MoreLikeThisQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/MoreLikeThisQueryBuilder.java index bfb579e0c3..ee0eff2a45 100644 --- a/core/src/main/java/org/elasticsearch/index/query/MoreLikeThisQueryBuilder.java +++ b/core/src/main/java/org/elasticsearch/index/query/MoreLikeThisQueryBuilder.java @@ -28,6 +28,7 @@ import org.apache.lucene.search.Query; import org.apache.lucene.util.BytesRef; import org.elasticsearch.ElasticsearchParseException; import org.elasticsearch.ExceptionsHelper; +import org.elasticsearch.Version; import org.elasticsearch.action.termvectors.MultiTermVectorsItemResponse; import org.elasticsearch.action.termvectors.MultiTermVectorsRequest; import org.elasticsearch.action.termvectors.MultiTermVectorsResponse; @@ -161,6 +162,7 @@ public class MoreLikeThisQueryBuilder extends AbstractQueryBuilder<MoreLikeThisQ private String type; private String id; private BytesReference doc; + private XContentType xContentType; private String[] fields; private Map<String, String> perFieldAnalyzer; private String routing; @@ -178,6 +180,7 @@ public class MoreLikeThisQueryBuilder extends AbstractQueryBuilder<MoreLikeThisQ this.type = copy.type; this.id = copy.id; this.doc = copy.doc; + this.xContentType = copy.xContentType; this.fields = copy.fields; this.perFieldAnalyzer = copy.perFieldAnalyzer; this.version = copy.version; @@ -214,6 +217,7 @@ public class MoreLikeThisQueryBuilder extends AbstractQueryBuilder<MoreLikeThisQ this.index = index; this.type = type; this.doc = doc.bytes(); + this.xContentType = doc.contentType(); } /** @@ -224,6 +228,11 @@ public class MoreLikeThisQueryBuilder extends AbstractQueryBuilder<MoreLikeThisQ type = in.readOptionalString(); if (in.readBoolean()) { doc = (BytesReference) in.readGenericValue(); + if (in.getVersion().after(Version.V_5_3_0_UNRELEASED)) { // TODO update to onOrAfter after backporting + xContentType = XContentType.readFrom(in); + } else { + xContentType = XContentFactory.xContentType(doc); + } } else { id = in.readString(); } @@ -241,6 +250,9 @@ public class MoreLikeThisQueryBuilder extends AbstractQueryBuilder<MoreLikeThisQ out.writeBoolean(doc != null); if (doc != null) { out.writeGenericValue(doc); + if (out.getVersion().after(Version.V_5_3_0_UNRELEASED)) { // TODO update to onOrAfter after backporting + xContentType.writeTo(out); + } } else { out.writeString(id); } @@ -325,6 +337,10 @@ public class MoreLikeThisQueryBuilder extends AbstractQueryBuilder<MoreLikeThisQ return this; } + XContentType xContentType() { + return xContentType; + } + /** * Convert this to a {@link TermVectorsRequest} for fetching the terms of the document. */ @@ -342,7 +358,7 @@ public class MoreLikeThisQueryBuilder extends AbstractQueryBuilder<MoreLikeThisQ .termStatistics(false); // for artificial docs to make sure that the id has changed in the item too if (doc != null) { - termVectorsRequest.doc(doc, true); + termVectorsRequest.doc(doc, true, xContentType); this.id = termVectorsRequest.id(); } return termVectorsRequest; @@ -366,6 +382,7 @@ public class MoreLikeThisQueryBuilder extends AbstractQueryBuilder<MoreLikeThisQ item.id = parser.text(); } else if (Field.DOC.match(currentFieldName)) { item.doc = jsonBuilder().copyCurrentStructure(parser).bytes(); + item.xContentType = XContentType.JSON; } else if (Field.FIELDS.match(currentFieldName)) { if (token == XContentParser.Token.START_ARRAY) { List<String> fields = new ArrayList<>(); @@ -416,12 +433,7 @@ public class MoreLikeThisQueryBuilder extends AbstractQueryBuilder<MoreLikeThisQ builder.field(Field.ID.getPreferredName(), this.id); } if (this.doc != null) { - XContentType contentType = XContentFactory.xContentType(this.doc); - if (contentType == builder.contentType()) { - builder.rawField(Field.DOC.getPreferredName(), this.doc); - } else { - builder.rawField(Field.DOC.getPreferredName(), doc); - } + builder.rawField(Field.DOC.getPreferredName(), this.doc, xContentType); } if (this.fields != null) { builder.array(Field.FIELDS.getPreferredName(), this.fields); diff --git a/core/src/main/java/org/elasticsearch/index/shard/TranslogRecoveryPerformer.java b/core/src/main/java/org/elasticsearch/index/shard/TranslogRecoveryPerformer.java index 6f4ae66a12..ad00e39097 100644 --- a/core/src/main/java/org/elasticsearch/index/shard/TranslogRecoveryPerformer.java +++ b/core/src/main/java/org/elasticsearch/index/shard/TranslogRecoveryPerformer.java @@ -22,6 +22,7 @@ import org.apache.logging.log4j.Logger; import org.elasticsearch.ElasticsearchException; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; +import org.elasticsearch.common.xcontent.XContentFactory; import org.elasticsearch.index.VersionType; import org.elasticsearch.index.engine.Engine; import org.elasticsearch.index.engine.IgnoreOnRecoveryEngineException; @@ -157,7 +158,8 @@ public class TranslogRecoveryPerformer { Translog.Index index = (Translog.Index) operation; // we set canHaveDuplicates to true all the time such that we de-optimze the translog case and ensure that all // autoGeneratedID docs that are coming from the primary are updated correctly. - Engine.Index engineIndex = IndexShard.prepareIndex(docMapper(index.type()), source(shardId.getIndexName(), index.type(), index.id(), index.source()) + Engine.Index engineIndex = IndexShard.prepareIndex(docMapper(index.type()), + source(shardId.getIndexName(), index.type(), index.id(), index.source(), XContentFactory.xContentType(index.source())) .routing(index.routing()).parent(index.parent()), index.seqNo(), index.primaryTerm(), index.version(), index.versionType().versionTypeForReplicationAndRecovery(), origin, index.getAutoGeneratedIdTimestamp(), true); maybeAddMappingUpdate(engineIndex.type(), engineIndex.parsedDoc().dynamicMappingsUpdate(), engineIndex.id(), allowMappingUpdates); 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 520cb13390..7981c89124 100644 --- a/core/src/main/java/org/elasticsearch/index/termvectors/TermVectorsService.java +++ b/core/src/main/java/org/elasticsearch/index/termvectors/TermVectorsService.java @@ -36,6 +36,7 @@ import org.elasticsearch.common.Strings; import org.elasticsearch.common.bytes.BytesReference; import org.elasticsearch.common.lucene.uid.Versions; 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; @@ -270,7 +271,8 @@ public class TermVectorsService { private static Fields generateTermVectorsFromDoc(IndexShard indexShard, TermVectorsRequest request) throws IOException { // parse the document, at the moment we do update the mapping, just like percolate - ParsedDocument parsedDocument = parseDocument(indexShard, indexShard.shardId().getIndexName(), request.type(), request.doc()); + ParsedDocument parsedDocument = + parseDocument(indexShard, indexShard.shardId().getIndexName(), request.type(), request.doc(), request.xContentType()); // select the right fields and generate term vectors ParseContext.Document doc = parsedDocument.rootDoc(); @@ -293,13 +295,15 @@ public class TermVectorsService { String[] values = doc.getValues(field.name()); getFields.add(new GetField(field.name(), Arrays.asList((Object[]) values))); } - return generateTermVectors(indexShard, XContentHelper.convertToMap(parsedDocument.source(), true).v2(), getFields, request.offsets(), request.perFieldAnalyzer(), seenFields); + return generateTermVectors(indexShard, XContentHelper.convertToMap(parsedDocument.source(), true, request.xContentType()).v2(), + getFields, request.offsets(), request.perFieldAnalyzer(), seenFields); } - private static ParsedDocument parseDocument(IndexShard indexShard, String index, String type, BytesReference doc) { + private static ParsedDocument parseDocument(IndexShard indexShard, String index, String type, BytesReference doc, + XContentType xContentType) { MapperService mapperService = indexShard.mapperService(); DocumentMapperForType docMapper = mapperService.documentMapperWithAutoCreate(type); - ParsedDocument parsedDocument = docMapper.getDocumentMapper().parse(source(index, type, "_id_for_tv_api", doc)); + ParsedDocument parsedDocument = docMapper.getDocumentMapper().parse(source(index, type, "_id_for_tv_api", doc, xContentType)); if (docMapper.getMapping() != null) { parsedDocument.addDynamicMappingsUpdate(docMapper.getMapping()); } |