diff --git a/rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/indices.create/20_synthetic_source.yml b/rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/indices.create/20_synthetic_source.yml index 3d95712d30b30..efb3641be55a6 100644 --- a/rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/indices.create/20_synthetic_source.yml +++ b/rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/indices.create/20_synthetic_source.yml @@ -1041,6 +1041,9 @@ doubly nested object: sub_nested_field: type: nested properties: + foo: + type: text + store: true obj1: enabled: false diff --git a/server/src/main/java/org/elasticsearch/index/mapper/NestedObjectMapper.java b/server/src/main/java/org/elasticsearch/index/mapper/NestedObjectMapper.java index 841515ff1aa90..adf36be6c3107 100644 --- a/server/src/main/java/org/elasticsearch/index/mapper/NestedObjectMapper.java +++ b/server/src/main/java/org/elasticsearch/index/mapper/NestedObjectMapper.java @@ -387,13 +387,16 @@ public Stream> storedFieldLoaders() { @Override public DocValuesLoader docValuesLoader(LeafReader leafReader, int[] docIdsInLeaf) throws IOException { - this.children = null; + // docs is set to null because the provided docIdsInLeaf represents the parent of the documents to be loaded in this nested + // context this.leafStoredFields = storedFieldsLoader.getLoader(leafReader.getContext(), null); this.leafSource = sourceLoader.leaf(leafReader, null); IndexSearcher searcher = new IndexSearcher(leafReader); searcher.setQueryCache(null); var childScorer = searcher.createWeight(childFilter, ScoreMode.COMPLETE_NO_SCORES, 1f).scorer(leafReader.getContext()); var parentDocs = parentBitSetProducer.get().getBitSet(leafReader.getContext()); + // reset children + this.children = null; return parentDoc -> { this.children = childScorer != null ? collectChildren(parentDoc, parentDocs, childScorer.iterator()) : List.of(); return children.size() > 0; diff --git a/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/mapper/SemanticTextFieldMapper.java b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/mapper/SemanticTextFieldMapper.java index 8324b121dfc4f..2e759cf12c92f 100644 --- a/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/mapper/SemanticTextFieldMapper.java +++ b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/mapper/SemanticTextFieldMapper.java @@ -8,6 +8,7 @@ package org.elasticsearch.xpack.inference.mapper; import org.apache.lucene.search.Query; +import org.apache.lucene.search.join.BitSetProducer; import org.apache.lucene.search.join.ScoreMode; import org.elasticsearch.cluster.metadata.InferenceFieldMetadata; import org.elasticsearch.common.Explicit; @@ -76,12 +77,13 @@ public class SemanticTextFieldMapper extends FieldMapper implements InferenceFie public static final String CONTENT_TYPE = "semantic_text"; public static final TypeParser PARSER = new TypeParser( - (n, c) -> new Builder(n, c.indexVersionCreated()), + (n, c) -> new Builder(n, c.indexVersionCreated(), query -> c.bitSetProducer(query)), List.of(notInMultiFields(CONTENT_TYPE), notFromDynamicTemplates(CONTENT_TYPE)) ); public static class Builder extends FieldMapper.Builder { private final IndexVersion indexVersionCreated; + private final Function bitSetProducer; private final Parameter inferenceId = Parameter.stringParam( "inference_id", @@ -108,10 +110,11 @@ public static class Builder extends FieldMapper.Builder { private Function inferenceFieldBuilder; - public Builder(String name, IndexVersion indexVersionCreated) { + public Builder(String name, IndexVersion indexVersionCreated, Function bitSetProducer) { super(name); this.indexVersionCreated = indexVersionCreated; - this.inferenceFieldBuilder = c -> createInferenceField(c, indexVersionCreated, modelSettings.get()); + this.bitSetProducer = bitSetProducer; + this.inferenceFieldBuilder = c -> createInferenceField(c, indexVersionCreated, bitSetProducer, modelSettings.get()); } public Builder setInferenceId(String id) { @@ -161,13 +164,22 @@ public SemanticTextFieldMapper build(MapperBuilderContext context) { indexVersionCreated, meta.getValue() ), - copyTo + copyTo, + bitSetProducer ); } } - private SemanticTextFieldMapper(String simpleName, MappedFieldType mappedFieldType, CopyTo copyTo) { + private final Function bitSetProducer; + + private SemanticTextFieldMapper( + String simpleName, + MappedFieldType mappedFieldType, + CopyTo copyTo, + Function bitSetProducer + ) { super(simpleName, mappedFieldType, MultiFields.empty(), copyTo); + this.bitSetProducer = bitSetProducer; } @Override @@ -179,7 +191,7 @@ public Iterator iterator() { @Override public FieldMapper.Builder getMergeBuilder() { - return new Builder(simpleName(), fieldType().indexVersionCreated).init(this); + return new Builder(simpleName(), fieldType().indexVersionCreated, bitSetProducer).init(this); } @Override @@ -214,7 +226,7 @@ protected void parseCreateField(DocumentParserContext context) throws IOExceptio final SemanticTextFieldMapper mapper; if (fieldType().getModelSettings() == null) { context.path().remove(); - Builder builder = (Builder) new Builder(simpleName(), fieldType().indexVersionCreated).init(this); + Builder builder = (Builder) new Builder(simpleName(), fieldType().indexVersionCreated, bitSetProducer).init(this); try { mapper = builder.setModelSettings(field.inference().modelSettings()) .setInferenceId(field.inference().inferenceId()) @@ -421,18 +433,20 @@ public QueryBuilder semanticQuery(InferenceResults inferenceResults, float boost private static ObjectMapper createInferenceField( MapperBuilderContext context, IndexVersion indexVersionCreated, + Function bitSetProducer, @Nullable SemanticTextField.ModelSettings modelSettings ) { return new ObjectMapper.Builder(INFERENCE_FIELD, Explicit.EXPLICIT_TRUE).dynamic(ObjectMapper.Dynamic.FALSE) - .add(createChunksField(indexVersionCreated, modelSettings)) + .add(createChunksField(indexVersionCreated, bitSetProducer, modelSettings)) .build(context); } private static NestedObjectMapper.Builder createChunksField( IndexVersion indexVersionCreated, + Function bitSetProducer, SemanticTextField.ModelSettings modelSettings ) { - NestedObjectMapper.Builder chunksField = new NestedObjectMapper.Builder(CHUNKS_FIELD, indexVersionCreated); + NestedObjectMapper.Builder chunksField = new NestedObjectMapper.Builder(CHUNKS_FIELD, indexVersionCreated, bitSetProducer); chunksField.dynamic(ObjectMapper.Dynamic.FALSE); KeywordFieldMapper.Builder chunkTextField = new KeywordFieldMapper.Builder(CHUNKED_TEXT_FIELD, indexVersionCreated).indexed(false) .docValues(false);