|
@@ -19,13 +19,13 @@ import org.elasticsearch.common.regex.Regex;
|
|
|
import org.elasticsearch.common.time.DateFormatter;
|
|
|
import org.elasticsearch.common.xcontent.LoggingDeprecationHandler;
|
|
|
import org.elasticsearch.common.xcontent.XContentHelper;
|
|
|
-import org.elasticsearch.core.Tuple;
|
|
|
import org.elasticsearch.index.IndexSettings;
|
|
|
import org.elasticsearch.index.analysis.IndexAnalyzers;
|
|
|
import org.elasticsearch.index.fielddata.IndexFieldDataCache;
|
|
|
import org.elasticsearch.index.query.SearchExecutionContext;
|
|
|
import org.elasticsearch.indices.breaker.NoneCircuitBreakerService;
|
|
|
import org.elasticsearch.search.lookup.SearchLookup;
|
|
|
+import org.elasticsearch.xcontent.DotExpandingXContentParser;
|
|
|
import org.elasticsearch.xcontent.NamedXContentRegistry;
|
|
|
import org.elasticsearch.xcontent.XContentBuilder;
|
|
|
import org.elasticsearch.xcontent.XContentParser;
|
|
@@ -85,10 +85,10 @@ public final class DocumentParser {
|
|
|
)
|
|
|
) {
|
|
|
context = new InternalDocumentParserContext(mappingLookup, indexSettings, indexAnalyzers, dateParserContext, source, parser);
|
|
|
- validateStart(parser);
|
|
|
+ validateStart(context.parser());
|
|
|
MetadataFieldMapper[] metadataFieldsMappers = mappingLookup.getMapping().getSortedMetadataMappers();
|
|
|
- internalParseDocument(mappingLookup.getMapping().getRoot(), metadataFieldsMappers, context, parser);
|
|
|
- validateEnd(parser);
|
|
|
+ internalParseDocument(mappingLookup.getMapping().getRoot(), metadataFieldsMappers, context);
|
|
|
+ validateEnd(context.parser());
|
|
|
} catch (Exception e) {
|
|
|
throw wrapInMapperParsingException(source, e);
|
|
|
}
|
|
@@ -109,28 +109,13 @@ public final class DocumentParser {
|
|
|
);
|
|
|
}
|
|
|
|
|
|
- private static boolean containsDisabledObjectMapper(ObjectMapper objectMapper, String[] subfields) {
|
|
|
- for (int i = 0; i < subfields.length - 1; ++i) {
|
|
|
- Mapper mapper = objectMapper.getMapper(subfields[i]);
|
|
|
- if (mapper instanceof ObjectMapper == false) {
|
|
|
- break;
|
|
|
- }
|
|
|
- objectMapper = (ObjectMapper) mapper;
|
|
|
- if (objectMapper.isEnabled() == false) {
|
|
|
- return true;
|
|
|
- }
|
|
|
- }
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
private static void internalParseDocument(
|
|
|
RootObjectMapper root,
|
|
|
MetadataFieldMapper[] metadataFieldsMappers,
|
|
|
- DocumentParserContext context,
|
|
|
- XContentParser parser
|
|
|
+ DocumentParserContext context
|
|
|
) throws IOException {
|
|
|
|
|
|
- final boolean emptyDoc = isEmptyDoc(root, parser);
|
|
|
+ final boolean emptyDoc = isEmptyDoc(root, context.parser());
|
|
|
|
|
|
for (MetadataFieldMapper metadataMapper : metadataFieldsMappers) {
|
|
|
metadataMapper.preParse(context);
|
|
@@ -138,7 +123,7 @@ public final class DocumentParser {
|
|
|
|
|
|
if (root.isEnabled() == false) {
|
|
|
// entire type is disabled
|
|
|
- parser.skipChildren();
|
|
|
+ context.parser().skipChildren();
|
|
|
} else if (emptyDoc == false) {
|
|
|
parseObjectOrNested(context, root);
|
|
|
}
|
|
@@ -457,39 +442,32 @@ public final class DocumentParser {
|
|
|
}
|
|
|
if (token == XContentParser.Token.START_OBJECT) {
|
|
|
// if we are just starting an OBJECT, advance, this is the object we are parsing, we need the name first
|
|
|
- token = parser.nextToken();
|
|
|
+ parser.nextToken();
|
|
|
}
|
|
|
|
|
|
- innerParseObject(context, mapper, parser, currentFieldName, token);
|
|
|
+ innerParseObject(context, mapper);
|
|
|
// restore the enable path flag
|
|
|
if (mapper.isNested()) {
|
|
|
nested(context, (NestedObjectMapper) mapper);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- private static void innerParseObject(
|
|
|
- DocumentParserContext context,
|
|
|
- ObjectMapper mapper,
|
|
|
- XContentParser parser,
|
|
|
- String currentFieldName,
|
|
|
- XContentParser.Token token
|
|
|
- ) throws IOException {
|
|
|
+ private static void innerParseObject(DocumentParserContext context, ObjectMapper mapper) throws IOException {
|
|
|
+
|
|
|
+ XContentParser.Token token = context.parser().currentToken();
|
|
|
+ String currentFieldName = context.parser().currentName();
|
|
|
assert token == XContentParser.Token.FIELD_NAME || token == XContentParser.Token.END_OBJECT;
|
|
|
- String[] paths = null;
|
|
|
+
|
|
|
while (token != XContentParser.Token.END_OBJECT) {
|
|
|
if (token == XContentParser.Token.FIELD_NAME) {
|
|
|
- currentFieldName = parser.currentName();
|
|
|
- paths = splitAndValidatePath(currentFieldName);
|
|
|
- if (containsDisabledObjectMapper(mapper, paths)) {
|
|
|
- parser.nextToken();
|
|
|
- parser.skipChildren();
|
|
|
- }
|
|
|
+ currentFieldName = context.parser().currentName();
|
|
|
+ splitAndValidatePath(currentFieldName);
|
|
|
} else if (token == XContentParser.Token.START_OBJECT) {
|
|
|
- parseObject(context, mapper, currentFieldName, paths);
|
|
|
+ parseObject(context, mapper, currentFieldName);
|
|
|
} else if (token == XContentParser.Token.START_ARRAY) {
|
|
|
- parseArray(context, mapper, currentFieldName, paths);
|
|
|
+ parseArray(context, mapper, currentFieldName);
|
|
|
} else if (token == XContentParser.Token.VALUE_NULL) {
|
|
|
- parseNullValue(context, mapper, currentFieldName, paths);
|
|
|
+ parseNullValue(context, mapper, currentFieldName);
|
|
|
} else if (token == null) {
|
|
|
throw new MapperParsingException(
|
|
|
"object mapping for ["
|
|
@@ -499,9 +477,9 @@ public final class DocumentParser {
|
|
|
+ "] as object, but got EOF, has a concrete value been provided to it?"
|
|
|
);
|
|
|
} else if (token.isValue()) {
|
|
|
- parseValue(context, mapper, currentFieldName, token, paths);
|
|
|
+ parseValue(context, mapper, currentFieldName, token);
|
|
|
}
|
|
|
- token = parser.nextToken();
|
|
|
+ token = context.parser().nextToken();
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -577,7 +555,8 @@ public final class DocumentParser {
|
|
|
parseCopyFields(context, copyToFields);
|
|
|
}
|
|
|
} else if (mapper instanceof FieldAliasMapper) {
|
|
|
- throw new IllegalArgumentException("Cannot write to a field alias [" + mapper.name() + "].");
|
|
|
+ String verb = context.isWithinCopyTo() ? "copy" : "write";
|
|
|
+ throw new MapperParsingException("Cannot " + verb + " to a field alias [" + mapper.name() + "].");
|
|
|
} else {
|
|
|
throw new IllegalStateException(
|
|
|
"The provided mapper [" + mapper.name() + "] has an unrecognized type [" + mapper.getClass().getSimpleName() + "]."
|
|
@@ -585,23 +564,19 @@ public final class DocumentParser {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- private static void parseObject(final DocumentParserContext context, ObjectMapper mapper, String currentFieldName, String[] paths)
|
|
|
- throws IOException {
|
|
|
+ private static void parseObject(final DocumentParserContext context, ObjectMapper mapper, String currentFieldName) throws IOException {
|
|
|
assert currentFieldName != null;
|
|
|
- Mapper objectMapper = getMapper(context, mapper, currentFieldName, paths);
|
|
|
+ Mapper objectMapper = getMapper(context, mapper, currentFieldName);
|
|
|
if (objectMapper != null) {
|
|
|
context.path().add(currentFieldName);
|
|
|
parseObjectOrField(context, objectMapper);
|
|
|
context.path().remove();
|
|
|
} else {
|
|
|
- currentFieldName = paths[paths.length - 1];
|
|
|
- Tuple<Integer, ObjectMapper> parentMapperTuple = getDynamicParentMapper(context, paths, mapper);
|
|
|
- ObjectMapper parentMapper = parentMapperTuple.v2();
|
|
|
- ObjectMapper.Dynamic dynamic = dynamicOrDefault(parentMapper, context);
|
|
|
+ ObjectMapper.Dynamic dynamic = dynamicOrDefault(mapper, context);
|
|
|
if (dynamic == ObjectMapper.Dynamic.STRICT) {
|
|
|
throw new StrictDynamicMappingException(mapper.fullPath(), currentFieldName);
|
|
|
} else if (dynamic == ObjectMapper.Dynamic.FALSE) {
|
|
|
- failIfMatchesRoutingPath(context, parentMapper, currentFieldName);
|
|
|
+ failIfMatchesRoutingPath(context, mapper, currentFieldName);
|
|
|
// not dynamic, read everything up to end object
|
|
|
context.parser().skipChildren();
|
|
|
} else {
|
|
@@ -614,21 +589,20 @@ public final class DocumentParser {
|
|
|
dynamicObjectMapper = dynamic.getDynamicFieldsBuilder().createDynamicObjectMapper(context, currentFieldName);
|
|
|
context.addDynamicMapper(dynamicObjectMapper);
|
|
|
}
|
|
|
+ if (dynamicObjectMapper instanceof NestedObjectMapper && context.isWithinCopyTo()) {
|
|
|
+ throw new MapperParsingException(
|
|
|
+ "It is forbidden to create dynamic nested objects ([" + dynamicObjectMapper.name() + "]) through `copy_to`"
|
|
|
+ );
|
|
|
+ }
|
|
|
context.path().add(currentFieldName);
|
|
|
parseObjectOrField(context, dynamicObjectMapper);
|
|
|
context.path().remove();
|
|
|
}
|
|
|
- for (int i = 0; i < parentMapperTuple.v1(); i++) {
|
|
|
- context.path().remove();
|
|
|
- }
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- private static void parseArray(DocumentParserContext context, ObjectMapper parentMapper, String lastFieldName, String[] paths)
|
|
|
- throws IOException {
|
|
|
- String arrayFieldName = lastFieldName;
|
|
|
-
|
|
|
- Mapper mapper = getLeafMapper(context, parentMapper, lastFieldName, paths);
|
|
|
+ private static void parseArray(DocumentParserContext context, ObjectMapper parentMapper, String lastFieldName) throws IOException {
|
|
|
+ Mapper mapper = getLeafMapper(context, parentMapper, lastFieldName);
|
|
|
if (mapper != null) {
|
|
|
// There is a concrete mapper for this field already. Need to check if the mapper
|
|
|
// expects an array, if so we pass the context straight to the mapper and if not
|
|
@@ -636,38 +610,31 @@ public final class DocumentParser {
|
|
|
if (parsesArrayValue(mapper)) {
|
|
|
parseObjectOrField(context, mapper);
|
|
|
} else {
|
|
|
- parseNonDynamicArray(context, parentMapper, lastFieldName, arrayFieldName);
|
|
|
+ parseNonDynamicArray(context, parentMapper, lastFieldName, lastFieldName);
|
|
|
}
|
|
|
} else {
|
|
|
- arrayFieldName = paths[paths.length - 1];
|
|
|
- lastFieldName = arrayFieldName;
|
|
|
- Tuple<Integer, ObjectMapper> parentMapperTuple = getDynamicParentMapper(context, paths, parentMapper);
|
|
|
- parentMapper = parentMapperTuple.v2();
|
|
|
ObjectMapper.Dynamic dynamic = dynamicOrDefault(parentMapper, context);
|
|
|
if (dynamic == ObjectMapper.Dynamic.STRICT) {
|
|
|
- throw new StrictDynamicMappingException(parentMapper.fullPath(), arrayFieldName);
|
|
|
+ throw new StrictDynamicMappingException(parentMapper.fullPath(), lastFieldName);
|
|
|
} else if (dynamic == ObjectMapper.Dynamic.FALSE) {
|
|
|
// TODO: shouldn't this skip, not parse?
|
|
|
- parseNonDynamicArray(context, parentMapper, lastFieldName, arrayFieldName);
|
|
|
+ parseNonDynamicArray(context, parentMapper, lastFieldName, lastFieldName);
|
|
|
} else {
|
|
|
- Mapper objectMapperFromTemplate = dynamic.getDynamicFieldsBuilder().createObjectMapperFromTemplate(context, arrayFieldName);
|
|
|
+ Mapper objectMapperFromTemplate = dynamic.getDynamicFieldsBuilder().createObjectMapperFromTemplate(context, lastFieldName);
|
|
|
if (objectMapperFromTemplate == null) {
|
|
|
- parseNonDynamicArray(context, parentMapper, lastFieldName, arrayFieldName);
|
|
|
+ parseNonDynamicArray(context, parentMapper, lastFieldName, lastFieldName);
|
|
|
} else {
|
|
|
if (parsesArrayValue(objectMapperFromTemplate)) {
|
|
|
context.addDynamicMapper(objectMapperFromTemplate);
|
|
|
- context.path().add(arrayFieldName);
|
|
|
+ context.path().add(lastFieldName);
|
|
|
parseObjectOrField(context, objectMapperFromTemplate);
|
|
|
context.path().remove();
|
|
|
} else {
|
|
|
- parseNonDynamicArray(context, parentMapper, lastFieldName, arrayFieldName);
|
|
|
+ parseNonDynamicArray(context, parentMapper, lastFieldName, lastFieldName);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
}
|
|
|
- for (int i = 0; i < parentMapperTuple.v1(); i++) {
|
|
|
- context.path().remove();
|
|
|
- }
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -683,14 +650,14 @@ public final class DocumentParser {
|
|
|
) throws IOException {
|
|
|
XContentParser parser = context.parser();
|
|
|
XContentParser.Token token;
|
|
|
- final String[] paths = splitAndValidatePath(lastFieldName);
|
|
|
+ splitAndValidatePath(lastFieldName);
|
|
|
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
|
|
|
if (token == XContentParser.Token.START_OBJECT) {
|
|
|
- parseObject(context, mapper, lastFieldName, paths);
|
|
|
+ parseObject(context, mapper, lastFieldName);
|
|
|
} else if (token == XContentParser.Token.START_ARRAY) {
|
|
|
- parseArray(context, mapper, lastFieldName, paths);
|
|
|
+ parseArray(context, mapper, lastFieldName);
|
|
|
} else if (token == XContentParser.Token.VALUE_NULL) {
|
|
|
- parseNullValue(context, mapper, lastFieldName, paths);
|
|
|
+ parseNullValue(context, mapper, lastFieldName);
|
|
|
} else if (token == null) {
|
|
|
throw new MapperParsingException(
|
|
|
"object mapping for ["
|
|
@@ -701,7 +668,7 @@ public final class DocumentParser {
|
|
|
);
|
|
|
} else {
|
|
|
assert token.isValue();
|
|
|
- parseValue(context, mapper, lastFieldName, token, paths);
|
|
|
+ parseValue(context, mapper, lastFieldName, token);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -710,8 +677,7 @@ public final class DocumentParser {
|
|
|
final DocumentParserContext context,
|
|
|
ObjectMapper parentMapper,
|
|
|
String currentFieldName,
|
|
|
- XContentParser.Token token,
|
|
|
- String[] paths
|
|
|
+ XContentParser.Token token
|
|
|
) throws IOException {
|
|
|
if (currentFieldName == null) {
|
|
|
throw new MapperParsingException(
|
|
@@ -723,24 +689,17 @@ public final class DocumentParser {
|
|
|
+ "]"
|
|
|
);
|
|
|
}
|
|
|
- Mapper mapper = getLeafMapper(context, parentMapper, currentFieldName, paths);
|
|
|
+ Mapper mapper = getLeafMapper(context, parentMapper, currentFieldName);
|
|
|
if (mapper != null) {
|
|
|
parseObjectOrField(context, mapper);
|
|
|
} else {
|
|
|
- currentFieldName = paths[paths.length - 1];
|
|
|
- Tuple<Integer, ObjectMapper> parentMapperTuple = getDynamicParentMapper(context, paths, parentMapper);
|
|
|
- parentMapper = parentMapperTuple.v2();
|
|
|
parseDynamicValue(context, parentMapper, currentFieldName, token);
|
|
|
- for (int i = 0; i < parentMapperTuple.v1(); i++) {
|
|
|
- context.path().remove();
|
|
|
- }
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- private static void parseNullValue(DocumentParserContext context, ObjectMapper parentMapper, String lastFieldName, String[] paths)
|
|
|
- throws IOException {
|
|
|
+ private static void parseNullValue(DocumentParserContext context, ObjectMapper parentMapper, String lastFieldName) throws IOException {
|
|
|
// we can only handle null values if we have mappings for them
|
|
|
- Mapper mapper = getLeafMapper(context, parentMapper, lastFieldName, paths);
|
|
|
+ Mapper mapper = getLeafMapper(context, parentMapper, lastFieldName);
|
|
|
if (mapper != null) {
|
|
|
// TODO: passing null to an object seems bogus?
|
|
|
parseObjectOrField(context, mapper);
|
|
@@ -782,7 +741,6 @@ public final class DocumentParser {
|
|
|
* Creates instances of the fields that the current field should be copied to
|
|
|
*/
|
|
|
private static void parseCopyFields(DocumentParserContext context, List<String> copyToFields) throws IOException {
|
|
|
- context = context.createCopyToContext();
|
|
|
for (String field : copyToFields) {
|
|
|
// In case of a hierarchy of nested documents, we need to figure out
|
|
|
// which document the field should go to
|
|
@@ -794,112 +752,11 @@ public final class DocumentParser {
|
|
|
}
|
|
|
}
|
|
|
assert targetDoc != null;
|
|
|
- final DocumentParserContext copyToContext;
|
|
|
- if (targetDoc == context.doc()) {
|
|
|
- copyToContext = context;
|
|
|
- } else {
|
|
|
- copyToContext = context.switchDoc(targetDoc);
|
|
|
- }
|
|
|
- parseCopy(field, copyToContext);
|
|
|
+ final DocumentParserContext copyToContext = context.createCopyToContext(field, targetDoc);
|
|
|
+ innerParseObject(copyToContext, context.root());
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- /**
|
|
|
- * Creates an copy of the current field with given field name and boost
|
|
|
- */
|
|
|
- private static void parseCopy(String field, DocumentParserContext context) throws IOException {
|
|
|
- Mapper mapper = context.mappingLookup().getMapper(field);
|
|
|
- if (mapper != null) {
|
|
|
- if (mapper instanceof FieldMapper) {
|
|
|
- ((FieldMapper) mapper).parse(context);
|
|
|
- } else if (mapper instanceof FieldAliasMapper) {
|
|
|
- throw new IllegalArgumentException("Cannot copy to a field alias [" + mapper.name() + "].");
|
|
|
- } else {
|
|
|
- throw new IllegalStateException(
|
|
|
- "The provided mapper [" + mapper.name() + "] has an unrecognized type [" + mapper.getClass().getSimpleName() + "]."
|
|
|
- );
|
|
|
- }
|
|
|
- } else {
|
|
|
- // The path of the dest field might be completely different from the current one so we need to reset it
|
|
|
- context = context.overridePath(new ContentPath(0));
|
|
|
-
|
|
|
- final String[] paths = splitAndValidatePath(field);
|
|
|
- final String fieldName = paths[paths.length - 1];
|
|
|
- Tuple<Integer, ObjectMapper> parentMapperTuple = getDynamicParentMapper(context, paths, null);
|
|
|
- ObjectMapper objectMapper = parentMapperTuple.v2();
|
|
|
- parseDynamicValue(context, objectMapper, fieldName, context.parser().currentToken());
|
|
|
- for (int i = 0; i < parentMapperTuple.v1(); i++) {
|
|
|
- context.path().remove();
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- private static Tuple<Integer, ObjectMapper> getDynamicParentMapper(
|
|
|
- DocumentParserContext context,
|
|
|
- final String[] paths,
|
|
|
- ObjectMapper currentParent
|
|
|
- ) {
|
|
|
- ObjectMapper mapper = currentParent == null ? context.root() : currentParent;
|
|
|
- int pathsAdded = 0;
|
|
|
- ObjectMapper parent = mapper;
|
|
|
- for (int i = 0; i < paths.length - 1; i++) {
|
|
|
- String name = paths[i];
|
|
|
- String currentPath = context.path().pathAsText(name);
|
|
|
- Mapper existingFieldMapper = context.mappingLookup().getMapper(currentPath);
|
|
|
- if (existingFieldMapper != null) {
|
|
|
- throw new MapperParsingException(
|
|
|
- "Could not dynamically add mapping for field [{}]. Existing mapping for [{}] must be of type object but found [{}].",
|
|
|
- null,
|
|
|
- String.join(".", paths),
|
|
|
- currentPath,
|
|
|
- existingFieldMapper.typeName()
|
|
|
- );
|
|
|
- }
|
|
|
- mapper = context.mappingLookup().objectMappers().get(currentPath);
|
|
|
- if (mapper == null) {
|
|
|
- // One mapping is missing, check if we are allowed to create a dynamic one.
|
|
|
- ObjectMapper.Dynamic dynamic = dynamicOrDefault(parent, context);
|
|
|
- if (dynamic == ObjectMapper.Dynamic.STRICT) {
|
|
|
- throw new StrictDynamicMappingException(parent.fullPath(), name);
|
|
|
- } else if (dynamic == ObjectMapper.Dynamic.FALSE) {
|
|
|
- // Should not dynamically create any more mappers so return the last mapper
|
|
|
- return new Tuple<>(pathsAdded, parent);
|
|
|
- } else if (dynamic == ObjectMapper.Dynamic.RUNTIME) {
|
|
|
- mapper = new NoOpObjectMapper(name, currentPath);
|
|
|
- } else {
|
|
|
- final Mapper fieldMapper = dynamic.getDynamicFieldsBuilder().createDynamicObjectMapper(context, name);
|
|
|
- if (fieldMapper instanceof ObjectMapper == false) {
|
|
|
- assert context.sourceToParse().dynamicTemplates().containsKey(currentPath)
|
|
|
- : "dynamic templates [" + context.sourceToParse().dynamicTemplates() + "]";
|
|
|
- throw new MapperParsingException(
|
|
|
- "Field ["
|
|
|
- + currentPath
|
|
|
- + "] must be an object; "
|
|
|
- + "but it's configured as ["
|
|
|
- + fieldMapper.typeName()
|
|
|
- + "] in dynamic template ["
|
|
|
- + context.sourceToParse().dynamicTemplates().get(currentPath)
|
|
|
- + "]"
|
|
|
- );
|
|
|
- }
|
|
|
- mapper = (ObjectMapper) fieldMapper;
|
|
|
- if (mapper.isNested()) {
|
|
|
- throw new MapperParsingException(
|
|
|
- "It is forbidden to create dynamic nested objects (["
|
|
|
- + currentPath
|
|
|
- + "]) through `copy_to` or dots in field names"
|
|
|
- );
|
|
|
- }
|
|
|
- context.addDynamicMapper(mapper);
|
|
|
- }
|
|
|
- }
|
|
|
- context.path().add(paths[i]);
|
|
|
- pathsAdded++;
|
|
|
- parent = mapper;
|
|
|
- }
|
|
|
- return new Tuple<>(pathsAdded, mapper);
|
|
|
- }
|
|
|
-
|
|
|
// find what the dynamic setting is given the current parse context and parent
|
|
|
private static ObjectMapper.Dynamic dynamicOrDefault(ObjectMapper parentMapper, DocumentParserContext context) {
|
|
|
ObjectMapper.Dynamic dynamic = parentMapper.dynamic();
|
|
@@ -927,48 +784,25 @@ public final class DocumentParser {
|
|
|
return dynamic;
|
|
|
}
|
|
|
|
|
|
- // looks up a child mapper, but takes into account field names that expand to objects
|
|
|
+ // looks up a child mapper
|
|
|
// returns null if no such child mapper exists - note that unlike getLeafMapper,
|
|
|
// we do not check for shadowing runtime fields because they only apply to leaf
|
|
|
// fields
|
|
|
- private static Mapper getMapper(final DocumentParserContext context, ObjectMapper objectMapper, String fieldName, String[] subfields) {
|
|
|
+ private static Mapper getMapper(final DocumentParserContext context, ObjectMapper objectMapper, String fieldName) {
|
|
|
String fieldPath = context.path().pathAsText(fieldName);
|
|
|
// Check if mapper is a metadata mapper first
|
|
|
Mapper mapper = context.getMetadataMapper(fieldPath);
|
|
|
if (mapper != null) {
|
|
|
return mapper;
|
|
|
}
|
|
|
-
|
|
|
- for (int i = 0; i < subfields.length - 1; ++i) {
|
|
|
- mapper = objectMapper.getMapper(subfields[i]);
|
|
|
- if (mapper instanceof ObjectMapper == false) {
|
|
|
- return null;
|
|
|
- }
|
|
|
- objectMapper = (ObjectMapper) mapper;
|
|
|
- if (objectMapper.isNested()) {
|
|
|
- throw new MapperParsingException(
|
|
|
- "Cannot add a value for field ["
|
|
|
- + fieldName
|
|
|
- + "] since one of the intermediate objects is mapped as a nested object: ["
|
|
|
- + mapper.name()
|
|
|
- + "]"
|
|
|
- );
|
|
|
- }
|
|
|
- }
|
|
|
- String leafName = subfields[subfields.length - 1];
|
|
|
- return objectMapper.getMapper(leafName);
|
|
|
+ return objectMapper.getMapper(fieldName);
|
|
|
}
|
|
|
|
|
|
// looks up a child mapper, taking into account field names that expand to objects
|
|
|
// if no mapper is found, checks to see if a runtime field with the specified
|
|
|
// field name exists and if so returns a no-op mapper to prevent indexing
|
|
|
- private static Mapper getLeafMapper(
|
|
|
- final DocumentParserContext context,
|
|
|
- ObjectMapper objectMapper,
|
|
|
- String fieldName,
|
|
|
- String[] subfields
|
|
|
- ) {
|
|
|
- Mapper mapper = getMapper(context, objectMapper, fieldName, subfields);
|
|
|
+ private static Mapper getLeafMapper(final DocumentParserContext context, ObjectMapper objectMapper, String fieldName) {
|
|
|
+ Mapper mapper = getMapper(context, objectMapper, fieldName);
|
|
|
if (mapper != null) {
|
|
|
return mapper;
|
|
|
}
|
|
@@ -1086,9 +920,9 @@ public final class DocumentParser {
|
|
|
Function<DateFormatter, MappingParserContext> parserContext,
|
|
|
SourceToParse source,
|
|
|
XContentParser parser
|
|
|
- ) {
|
|
|
+ ) throws IOException {
|
|
|
super(mappingLookup, indexSettings, indexAnalyzers, parserContext, source);
|
|
|
- this.parser = parser;
|
|
|
+ this.parser = DotExpandingXContentParser.expandDots(parser);
|
|
|
this.document = new LuceneDocument();
|
|
|
this.documents.add(document);
|
|
|
this.maxAllowedNumNestedDocs = indexSettings().getMappingNestedDocsLimit();
|