Skip to content

Commit 8b9f084

Browse files
authored
Revert change (#90674) (#103865) (#103933)
Reverts #90674 The revert is not perfectly clean as there are some minor adjustments to account for later changes. This is in contrast with: #103858 closes: #103011
1 parent cd8e1e6 commit 8b9f084

File tree

10 files changed

+127
-97
lines changed

10 files changed

+127
-97
lines changed

docs/changelog/103865.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
pr: 103865
2+
summary: Revert change
3+
area: Mapping
4+
type: bug
5+
issues: []

server/src/main/java/org/elasticsearch/index/mapper/DocumentParser.java

Lines changed: 12 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -250,8 +250,8 @@ static Mapping createDynamicUpdate(DocumentParserContext context) {
250250
return null;
251251
}
252252
RootObjectMapper.Builder rootBuilder = context.updateRoot();
253-
context.getDynamicMappers()
254-
.forEach((name, builders) -> builders.forEach(builder -> rootBuilder.addDynamic(name, null, builder, context)));
253+
context.getDynamicMappers().forEach(mapper -> rootBuilder.addDynamic(mapper.name(), null, mapper, context));
254+
255255
for (RuntimeField runtimeField : context.getDynamicRuntimeFields()) {
256256
rootBuilder.addRuntimeField(runtimeField);
257257
}
@@ -484,20 +484,13 @@ private static void parseObjectDynamic(DocumentParserContext context, String cur
484484
// not dynamic, read everything up to end object
485485
context.parser().skipChildren();
486486
} else {
487-
Mapper.Builder dynamicObjectBuilder = null;
488487
Mapper dynamicObjectMapper;
489488
if (context.dynamic() == ObjectMapper.Dynamic.RUNTIME) {
490489
// with dynamic:runtime all leaf fields will be runtime fields unless explicitly mapped,
491490
// hence we don't dynamically create empty objects under properties, but rather carry around an artificial object mapper
492491
dynamicObjectMapper = new NoOpObjectMapper(currentFieldName, context.path().pathAsText(currentFieldName));
493492
} else {
494-
dynamicObjectBuilder = DynamicFieldsBuilder.findTemplateBuilderForObject(context, currentFieldName);
495-
if (dynamicObjectBuilder == null) {
496-
dynamicObjectBuilder = new ObjectMapper.Builder(currentFieldName, ObjectMapper.Defaults.SUBOBJECTS).enabled(
497-
ObjectMapper.Defaults.ENABLED
498-
);
499-
}
500-
dynamicObjectMapper = dynamicObjectBuilder.build(context.createDynamicMapperBuilderContext());
493+
dynamicObjectMapper = DynamicFieldsBuilder.createDynamicObjectMapper(context, currentFieldName);
501494
}
502495
if (context.parent().subobjects() == false) {
503496
if (dynamicObjectMapper instanceof NestedObjectMapper) {
@@ -519,8 +512,8 @@ private static void parseObjectDynamic(DocumentParserContext context, String cur
519512
}
520513

521514
}
522-
if (context.dynamic() != ObjectMapper.Dynamic.RUNTIME && dynamicObjectBuilder != null) {
523-
context.addDynamicMapper(dynamicObjectMapper.name(), dynamicObjectBuilder);
515+
if (context.dynamic() != ObjectMapper.Dynamic.RUNTIME) {
516+
context.addDynamicMapper(dynamicObjectMapper);
524517
}
525518
if (dynamicObjectMapper instanceof NestedObjectMapper && context.isWithinCopyTo()) {
526519
throwOnCreateDynamicNestedViaCopyTo(dynamicObjectMapper, context);
@@ -557,13 +550,12 @@ private static void parseArrayDynamic(DocumentParserContext context, String curr
557550
if (context.dynamic() == ObjectMapper.Dynamic.FALSE) {
558551
context.parser().skipChildren();
559552
} else {
560-
Mapper.Builder objectBuilderFromTemplate = DynamicFieldsBuilder.findTemplateBuilderForObject(context, currentFieldName);
561-
if (objectBuilderFromTemplate == null) {
553+
Mapper objectMapperFromTemplate = DynamicFieldsBuilder.createObjectMapperFromTemplate(context, currentFieldName);
554+
if (objectMapperFromTemplate == null) {
562555
parseNonDynamicArray(context, currentFieldName, currentFieldName);
563556
} else {
564-
Mapper objectMapperFromTemplate = objectBuilderFromTemplate.build(context.createDynamicMapperBuilderContext());
565557
if (parsesArrayValue(objectMapperFromTemplate)) {
566-
context.addDynamicMapper(objectMapperFromTemplate.name(), objectBuilderFromTemplate);
558+
context.addDynamicMapper(objectMapperFromTemplate);
567559
context.path().add(currentFieldName);
568560
parseObjectOrField(context, objectMapperFromTemplate);
569561
context.path().remove();
@@ -606,7 +598,7 @@ private static void postProcessDynamicArrayMapping(DocumentParserContext context
606598
if (context.indexSettings().getIndexVersionCreated().onOrAfter(DYNAMICALLY_MAP_DENSE_VECTORS_INDEX_VERSION)) {
607599
final MapperBuilderContext builderContext = context.createDynamicMapperBuilderContext();
608600
final String fullFieldName = builderContext.buildFullName(fieldName);
609-
final List<Mapper.Builder> mappers = context.getDynamicMappers(fullFieldName);
601+
final List<Mapper> mappers = context.getDynamicMappers(fullFieldName);
610602
if (mappers == null
611603
|| context.isFieldAppliedFromTemplate(fullFieldName)
612604
|| context.isCopyToField(fullFieldName)
@@ -615,8 +607,7 @@ private static void postProcessDynamicArrayMapping(DocumentParserContext context
615607
// Anything that is NOT a number or anything that IS a number but not mapped to `float` should NOT be mapped to dense_vector
616608
|| mappers.stream()
617609
.anyMatch(
618-
m -> m instanceof NumberFieldMapper.Builder == false
619-
|| ((NumberFieldMapper.Builder) m).type != NumberFieldMapper.NumberType.FLOAT
610+
m -> m instanceof NumberFieldMapper == false || ((NumberFieldMapper) m).type() != NumberFieldMapper.NumberType.FLOAT
620611
)) {
621612
return;
622613
}
@@ -625,7 +616,8 @@ private static void postProcessDynamicArrayMapping(DocumentParserContext context
625616
fieldName,
626617
context.indexSettings().getIndexVersionCreated()
627618
);
628-
context.updateDynamicMappers(fullFieldName, builder);
619+
DenseVectorFieldMapper denseVectorFieldMapper = builder.build(builderContext);
620+
context.updateDynamicMappers(fullFieldName, List.of(denseVectorFieldMapper));
629621
}
630622
}
631623

server/src/main/java/org/elasticsearch/index/mapper/DocumentParserContext.java

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@
2222
import java.util.ArrayList;
2323
import java.util.Collection;
2424
import java.util.Collections;
25+
import java.util.HashMap;
2526
import java.util.HashSet;
26-
import java.util.LinkedHashMap;
2727
import java.util.List;
2828
import java.util.Map;
2929
import java.util.Set;
@@ -84,9 +84,9 @@ protected void addDoc(LuceneDocument doc) {
8484
private final MappingParserContext mappingParserContext;
8585
private final SourceToParse sourceToParse;
8686
private final Set<String> ignoredFields;
87-
private final Map<String, List<Mapper.Builder>> dynamicMappers;
87+
private final Map<String, List<Mapper>> dynamicMappers;
8888
private final Set<String> newFieldsSeen;
89-
private final Map<String, ObjectMapper.Builder> dynamicObjectMappers;
89+
private final Map<String, ObjectMapper> dynamicObjectMappers;
9090
private final List<RuntimeField> dynamicRuntimeFields;
9191
private final DocumentDimensions dimensions;
9292
private final ObjectMapper parent;
@@ -102,9 +102,9 @@ private DocumentParserContext(
102102
MappingParserContext mappingParserContext,
103103
SourceToParse sourceToParse,
104104
Set<String> ignoreFields,
105-
Map<String, List<Mapper.Builder>> dynamicMappers,
105+
Map<String, List<Mapper>> dynamicMappers,
106106
Set<String> newFieldsSeen,
107-
Map<String, ObjectMapper.Builder> dynamicObjectMappers,
107+
Map<String, ObjectMapper> dynamicObjectMappers,
108108
List<RuntimeField> dynamicRuntimeFields,
109109
String id,
110110
Field version,
@@ -166,9 +166,9 @@ protected DocumentParserContext(
166166
mappingParserContext,
167167
source,
168168
new HashSet<>(),
169-
new LinkedHashMap<>(),
169+
new HashMap<>(),
170170
new HashSet<>(),
171-
new LinkedHashMap<>(),
171+
new HashMap<>(),
172172
new ArrayList<>(),
173173
null,
174174
null,
@@ -304,29 +304,29 @@ public boolean isCopyToField(String name) {
304304
/**
305305
* Add a new mapper dynamically created while parsing.
306306
*/
307-
public final void addDynamicMapper(String fullName, Mapper.Builder builder) {
307+
public final void addDynamicMapper(Mapper mapper) {
308308
// eagerly check object depth limit here to avoid stack overflow errors
309-
if (builder instanceof ObjectMapper.Builder) {
310-
MappingLookup.checkObjectDepthLimit(indexSettings().getMappingDepthLimit(), fullName);
309+
if (mapper instanceof ObjectMapper) {
310+
MappingLookup.checkObjectDepthLimit(indexSettings().getMappingDepthLimit(), mapper.name());
311311
}
312312

313313
// eagerly check field name limit here to avoid OOM errors
314314
// only check fields that are not already mapped or tracked in order to avoid hitting field limit too early via double-counting
315315
// note that existing fields can also receive dynamic mapping updates (e.g. constant_keyword to fix the value)
316-
if (mappingLookup.getMapper(fullName) == null
317-
&& mappingLookup.objectMappers().containsKey(fullName) == false
318-
&& newFieldsSeen.add(fullName)) {
316+
if (mappingLookup.getMapper(mapper.name()) == null
317+
&& mappingLookup.objectMappers().containsKey(mapper.name()) == false
318+
&& newFieldsSeen.add(mapper.name())) {
319319
mappingLookup.checkFieldLimit(indexSettings().getMappingTotalFieldsLimit(), newFieldsSeen.size());
320320
}
321-
if (builder instanceof ObjectMapper.Builder objectMapper) {
322-
dynamicObjectMappers.put(fullName, objectMapper);
321+
if (mapper instanceof ObjectMapper objectMapper) {
322+
dynamicObjectMappers.put(objectMapper.name(), objectMapper);
323323
// dynamic object mappers may have been obtained from applying a dynamic template, in which case their definition may contain
324324
// sub-fields as well as sub-objects that need to be added to the mappings
325-
for (Mapper.Builder submapper : objectMapper.subBuilders()) {
325+
for (Mapper submapper : objectMapper.mappers.values()) {
326326
// we could potentially skip the step of adding these to the dynamic mappers, because their parent is already added to
327327
// that list, and what is important is that all of the intermediate objects are added to the dynamic object mappers so that
328328
// they can be looked up once sub-fields need to be added to them. For simplicity, we treat these like any other object
329-
addDynamicMapper(fullName + "." + submapper.name, submapper);
329+
addDynamicMapper(submapper);
330330
}
331331
}
332332

@@ -336,7 +336,7 @@ public final void addDynamicMapper(String fullName, Mapper.Builder builder) {
336336
// dynamically mapped objects when the incoming document defines no sub-fields in them:
337337
// 1) by default, they would be empty containers in the mappings, is it then important to map them?
338338
// 2) they can be the result of applying a dynamic template which may define sub-fields or set dynamic, enabled or subobjects.
339-
dynamicMappers.computeIfAbsent(fullName, k -> new ArrayList<>()).add(builder);
339+
dynamicMappers.computeIfAbsent(mapper.name(), k -> new ArrayList<>()).add(mapper);
340340
}
341341

342342
/**
@@ -345,8 +345,8 @@ public final void addDynamicMapper(String fullName, Mapper.Builder builder) {
345345
* Consists of a all {@link Mapper}s that will need to be added to their respective parent {@link ObjectMapper}s in order
346346
* to become part of the resulting dynamic mapping update.
347347
*/
348-
public final Map<String, List<Mapper.Builder>> getDynamicMappers() {
349-
return dynamicMappers;
348+
public final List<Mapper> getDynamicMappers() {
349+
return dynamicMappers.values().stream().flatMap(List::stream).toList();
350350
}
351351

352352
/**
@@ -355,13 +355,13 @@ public final Map<String, List<Mapper.Builder>> getDynamicMappers() {
355355
* @param fieldName Full field name with dot-notation.
356356
* @return List of Mappers or null
357357
*/
358-
public final List<Mapper.Builder> getDynamicMappers(String fieldName) {
358+
public final List<Mapper> getDynamicMappers(String fieldName) {
359359
return dynamicMappers.get(fieldName);
360360
}
361361

362-
public void updateDynamicMappers(String name, Mapper.Builder mapper) {
362+
public void updateDynamicMappers(String name, List<Mapper> mappers) {
363363
dynamicMappers.remove(name);
364-
dynamicMappers.put(name, List.of(mapper));
364+
mappers.forEach(this::addDynamicMapper);
365365
}
366366

367367
/**
@@ -371,7 +371,7 @@ public void updateDynamicMappers(String name, Mapper.Builder mapper) {
371371
* Holds a flat set of object mappers, meaning that an object field named <code>foo.bar</code> can be looked up directly with its
372372
* dotted name.
373373
*/
374-
final ObjectMapper.Builder getDynamicObjectMapper(String name) {
374+
final ObjectMapper getDynamicObjectMapper(String name) {
375375
return dynamicObjectMappers.get(name);
376376
}
377377

server/src/main/java/org/elasticsearch/index/mapper/DynamicFieldsBuilder.java

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,25 @@ void createDynamicFieldFromValue(final DocumentParserContext context, String nam
155155
}
156156
}
157157

158+
/**
159+
* Returns a dynamically created object mapper, eventually based on a matching dynamic template.
160+
*/
161+
static Mapper createDynamicObjectMapper(DocumentParserContext context, String name) {
162+
Mapper mapper = createObjectMapperFromTemplate(context, name);
163+
return mapper != null
164+
? mapper
165+
: new ObjectMapper.Builder(name, ObjectMapper.Defaults.SUBOBJECTS).enabled(ObjectMapper.Defaults.ENABLED)
166+
.build(context.createDynamicMapperBuilderContext());
167+
}
168+
169+
/**
170+
* Returns a dynamically created object mapper, based exclusively on a matching dynamic template, null otherwise.
171+
*/
172+
static Mapper createObjectMapperFromTemplate(DocumentParserContext context, String name) {
173+
Mapper.Builder templateBuilder = findTemplateBuilderForObject(context, name);
174+
return templateBuilder == null ? null : templateBuilder.build(context.createDynamicMapperBuilderContext());
175+
}
176+
158177
/**
159178
* Creates a dynamic string field based on a matching dynamic template.
160179
* No field is created in case there is no matching dynamic template.
@@ -234,10 +253,7 @@ private static boolean applyMatchingTemplate(
234253
return true;
235254
}
236255

237-
/**
238-
* Returns a dynamically created object builder, based exclusively on a matching dynamic template, null otherwise.
239-
*/
240-
static Mapper.Builder findTemplateBuilderForObject(DocumentParserContext context, String name) {
256+
private static Mapper.Builder findTemplateBuilderForObject(DocumentParserContext context, String name) {
241257
DynamicTemplate.XContentFieldType matchType = DynamicTemplate.XContentFieldType.OBJECT;
242258
DynamicTemplate dynamicTemplate = context.findDynamicTemplate(name, matchType);
243259
if (dynamicTemplate == null) {
@@ -293,7 +309,7 @@ private static final class Concrete implements Strategy {
293309

294310
void createDynamicField(Mapper.Builder builder, DocumentParserContext context) throws IOException {
295311
Mapper mapper = builder.build(context.createDynamicMapperBuilderContext());
296-
context.addDynamicMapper(mapper.name(), builder);
312+
context.addDynamicMapper(mapper);
297313
parseField.accept(context, mapper);
298314
}
299315

server/src/main/java/org/elasticsearch/index/mapper/NumberFieldMapper.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ public static class Builder extends FieldMapper.Builder {
118118
private final Parameter<Map<String, String>> meta = Parameter.metaParam();
119119

120120
private final ScriptCompiler scriptCompiler;
121-
public final NumberType type;
121+
private final NumberType type;
122122

123123
private boolean allowMultipleValues = true;
124124
private final IndexVersion indexCreatedVersion;
@@ -1732,6 +1732,10 @@ public NumberFieldType fieldType() {
17321732
return (NumberFieldType) super.fieldType();
17331733
}
17341734

1735+
public NumberType type() {
1736+
return type;
1737+
}
1738+
17351739
@Override
17361740
protected String contentType() {
17371741
return fieldType().type.typeName();

0 commit comments

Comments
 (0)