Browse Source

Change synthetic source logic for constant_keyword (#117182) (#117209)

* Change synthetic source logic for constant_keyword

* Update docs/changelog/117182.yaml

(cherry picked from commit 3a1bc05ad0ff7651d08c978c37c26c007f87d3ff)
Oleksandr Kolomiiets 10 months ago
parent
commit
02e58309ee

+ 6 - 0
docs/changelog/117182.yaml

@@ -0,0 +1,6 @@
+pr: 117182
+summary: Change synthetic source logic for `constant_keyword`
+area: Mapping
+type: bug
+issues:
+ - 117083

+ 8 - 36
x-pack/plugin/mapper-constant-keyword/src/main/java/org/elasticsearch/xpack/constantkeyword/mapper/ConstantKeywordFieldMapper.java

@@ -8,7 +8,6 @@
 package org.elasticsearch.xpack.constantkeyword.mapper;
 
 import org.apache.lucene.index.IndexReader;
-import org.apache.lucene.index.LeafReader;
 import org.apache.lucene.index.TermsEnum;
 import org.apache.lucene.search.MatchAllDocsQuery;
 import org.apache.lucene.search.MatchNoDocsQuery;
@@ -57,7 +56,6 @@ import java.util.Collections;
 import java.util.Locale;
 import java.util.Map;
 import java.util.Objects;
-import java.util.stream.Stream;
 
 /**
  * A {@link FieldMapper} that assigns every document the same value.
@@ -352,40 +350,14 @@ public class ConstantKeywordFieldMapper extends FieldMapper {
             return new SyntheticSourceSupport.Native(SourceLoader.SyntheticFieldLoader.NOTHING);
         }
 
-        var loader = new SourceLoader.SyntheticFieldLoader() {
-            @Override
-            public Stream<Map.Entry<String, StoredFieldLoader>> storedFieldLoaders() {
-                return Stream.of();
-            }
-
-            @Override
-            public DocValuesLoader docValuesLoader(LeafReader reader, int[] docIdsInLeaf) {
-                return docId -> true;
-            }
-
-            @Override
-            public boolean hasValue() {
-                return true;
-            }
-
-            @Override
-            public void write(XContentBuilder b) throws IOException {
-                if (fieldType().value != null) {
-                    b.field(leafName(), fieldType().value);
-                }
-            }
-
-            @Override
-            public void reset() {
-                // NOOP
-            }
-
-            @Override
-            public String fieldName() {
-                return fullPath();
-            }
-        };
+        /*
+        If there was no value in the document, synthetic source should not have the value too.
+        This is consistent with stored source behavior and is important for scenarios
+        like reindexing into an index that has a different value of this value in the mapping.
 
-        return new SyntheticSourceSupport.Native(loader);
+        In order to do that we use fallback logic which implements exactly such logic (_source only contains value
+        if it was in the original document).
+         */
+        return new SyntheticSourceSupport.Fallback();
     }
 }

+ 11 - 0
x-pack/plugin/mapper-constant-keyword/src/test/java/org/elasticsearch/xpack/constantkeyword/mapper/ConstantKeywordFieldMapperTests.java

@@ -333,6 +333,17 @@ public class ConstantKeywordFieldMapperTests extends MapperTestCase {
         assertThat(syntheticSource(mapper, b -> {}), equalTo("{}"));
     }
 
+    public void testNoValueInDocumentSyntheticSource() throws IOException {
+        DocumentMapper mapper = createSytheticSourceMapperService(mapping(b -> {
+            b.startObject("field");
+            b.field("type", "constant_keyword");
+            b.field("value", randomAlphaOfLength(5));
+            b.endObject();
+        })).documentMapper();
+
+        assertThat(syntheticSource(mapper, b -> {}), equalTo("{}"));
+    }
+
     @Override
     protected boolean supportsEmptyInputArray() {
         return false;