Skip to content

Commit

Permalink
Change synthetic source logic for constant_keyword to not rely on fal…
Browse files Browse the repository at this point in the history
…lback synthetic source (#119323) (#119329)
  • Loading branch information
lkts authored Dec 27, 2024
1 parent 43620b2 commit 41c3769
Show file tree
Hide file tree
Showing 2 changed files with 117 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

package org.elasticsearch.xpack.constantkeyword.mapper;

import org.apache.lucene.document.SortedNumericDocValuesField;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.TermsEnum;
import org.apache.lucene.search.MatchAllDocsQuery;
Expand Down Expand Up @@ -40,6 +41,7 @@
import org.elasticsearch.index.mapper.Mapper;
import org.elasticsearch.index.mapper.MapperBuilderContext;
import org.elasticsearch.index.mapper.MapperParsingException;
import org.elasticsearch.index.mapper.SortedNumericDocValuesSyntheticFieldLoader;
import org.elasticsearch.index.mapper.SourceLoader;
import org.elasticsearch.index.mapper.ValueFetcher;
import org.elasticsearch.index.query.QueryRewriteContext;
Expand Down Expand Up @@ -335,6 +337,12 @@ protected void parseCreateField(DocumentParserContext context) throws IOExceptio
+ "]"
);
}

if (context.mappingLookup().isSourceSynthetic()) {
// Remember which documents had value in source so that it can be correctly
// reconstructed in synthetic source
context.doc().add(new SortedNumericDocValuesField(fieldType().name(), 1));
}
}

@Override
Expand All @@ -344,20 +352,19 @@ protected String contentType() {

@Override
protected SyntheticSourceSupport syntheticSourceSupport() {
String value = fieldType().value();
String const_value = fieldType().value();

if (value == null) {
if (const_value == null) {
return new SyntheticSourceSupport.Native(SourceLoader.SyntheticFieldLoader.NOTHING);
}

/*
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.
var loader = new SortedNumericDocValuesSyntheticFieldLoader(fullPath(), leafName(), false) {
@Override
protected void writeValue(XContentBuilder b, long ignored) throws IOException {
b.value(const_value);
}
};

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();
return new SyntheticSourceSupport.Native(loader);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,103 @@ constant_keyword:
hits.hits.0._source:
kwd: foo
const_kwd: bar

---
constant_keyword update value:
- requires:
cluster_features: [ "mapper.constant_keyword.synthetic_source_write_fix" ]
reason: "Behavior fix"

- do:
indices.create:
index: test
body:
settings:
index:
mapping.source.mode: synthetic
mappings:
properties:
const_kwd:
type: constant_keyword
kwd:
type: keyword

- do:
index:
index: test
id: 1
refresh: true
body:
kwd: foo

- do:
index:
index: test
id: 2
refresh: true
body:
const_kwd: bar

- do:
index:
index: test
id: 3
refresh: true
body:
kwd: foo

- do:
index:
index: test
id: 4
refresh: true
body:
const_kwd: bar

- do:
search:
index: test
body:
query:
ids:
values: [1]

- match:
hits.hits.0._source:
kwd: foo

- do:
search:
index: test
body:
query:
ids:
values: [2]

- match:
hits.hits.0._source:
const_kwd: bar

- do:
search:
index: test
body:
query:
ids:
values: [3]

- match:
hits.hits.0._source:
kwd: foo

- do:
search:
index: test
body:
query:
ids:
values: [4]

- match:
hits.hits.0._source:
const_kwd: bar

0 comments on commit 41c3769

Please sign in to comment.