3535import org .elasticsearch .common .text .UTF8DecodingReader ;
3636import org .elasticsearch .common .unit .Fuzziness ;
3737import org .elasticsearch .index .IndexVersion ;
38+ import org .elasticsearch .index .IndexVersions ;
3839import org .elasticsearch .index .analysis .IndexAnalyzers ;
3940import org .elasticsearch .index .analysis .NamedAnalyzer ;
4041import org .elasticsearch .index .fielddata .FieldDataContext ;
@@ -105,8 +106,15 @@ public static class Builder extends FieldMapper.Builder {
105106
106107 private final TextParams .Analyzers analyzers ;
107108 private final boolean withinMultiField ;
109+ private final boolean storedFieldInBinaryFormat ;
108110
109- public Builder (String name , IndexVersion indexCreatedVersion , IndexAnalyzers indexAnalyzers , boolean withinMultiField ) {
111+ public Builder (
112+ String name ,
113+ IndexVersion indexCreatedVersion ,
114+ IndexAnalyzers indexAnalyzers ,
115+ boolean withinMultiField ,
116+ boolean storedFieldInBinaryFormat
117+ ) {
110118 super (name );
111119 this .indexCreatedVersion = indexCreatedVersion ;
112120 this .analyzers = new TextParams .Analyzers (
@@ -116,6 +124,7 @@ public Builder(String name, IndexVersion indexCreatedVersion, IndexAnalyzers ind
116124 indexCreatedVersion
117125 );
118126 this .withinMultiField = withinMultiField ;
127+ this .storedFieldInBinaryFormat = storedFieldInBinaryFormat ;
119128 }
120129
121130 @ Override
@@ -135,7 +144,8 @@ private MatchOnlyTextFieldType buildFieldType(MapperBuilderContext context) {
135144 context .isSourceSynthetic (),
136145 meta .getValue (),
137146 withinMultiField ,
138- multiFieldsBuilder .hasSyntheticSourceCompatibleKeywordField ()
147+ multiFieldsBuilder .hasSyntheticSourceCompatibleKeywordField (),
148+ storedFieldInBinaryFormat
139149 );
140150 return ft ;
141151 }
@@ -155,8 +165,22 @@ public MatchOnlyTextFieldMapper build(MapperBuilderContext context) {
155165 }
156166 }
157167
168+ private static boolean isSyntheticSourceStoredFieldInBinaryFormat (IndexVersion indexCreatedVersion ) {
169+ return indexCreatedVersion .onOrAfter (IndexVersions .MATCH_ONLY_TEXT_STORED_AS_BYTES )
170+ || indexCreatedVersion .between (
171+ IndexVersions .MATCH_ONLY_TEXT_STORED_AS_BYTES_BACKPORT_8_X ,
172+ IndexVersions .UPGRADE_TO_LUCENE_10_0_0
173+ );
174+ }
175+
158176 public static final TypeParser PARSER = new TypeParser (
159- (n , c ) -> new Builder (n , c .indexVersionCreated (), c .getIndexAnalyzers (), c .isWithinMultiField ())
177+ (n , c ) -> new Builder (
178+ n ,
179+ c .indexVersionCreated (),
180+ c .getIndexAnalyzers (),
181+ c .isWithinMultiField (),
182+ isSyntheticSourceStoredFieldInBinaryFormat (c .indexVersionCreated ())
183+ )
160184 );
161185
162186 public static class MatchOnlyTextFieldType extends StringFieldType {
@@ -167,6 +191,7 @@ public static class MatchOnlyTextFieldType extends StringFieldType {
167191
168192 private final boolean withinMultiField ;
169193 private final boolean hasCompatibleMultiFields ;
194+ private final boolean storedFieldInBinaryFormat ;
170195
171196 public MatchOnlyTextFieldType (
172197 String name ,
@@ -175,14 +200,16 @@ public MatchOnlyTextFieldType(
175200 boolean isSyntheticSource ,
176201 Map <String , String > meta ,
177202 boolean withinMultiField ,
178- boolean hasCompatibleMultiFields
203+ boolean hasCompatibleMultiFields ,
204+ boolean storedFieldInBinaryFormat
179205 ) {
180206 super (name , true , false , false , tsi , meta );
181207 this .indexAnalyzer = Objects .requireNonNull (indexAnalyzer );
182208 this .textFieldType = new TextFieldType (name , isSyntheticSource );
183209 this .originalName = isSyntheticSource ? name + "._original" : null ;
184210 this .withinMultiField = withinMultiField ;
185211 this .hasCompatibleMultiFields = hasCompatibleMultiFields ;
212+ this .storedFieldInBinaryFormat = storedFieldInBinaryFormat ;
186213 }
187214
188215 public MatchOnlyTextFieldType (String name ) {
@@ -193,6 +220,7 @@ public MatchOnlyTextFieldType(String name) {
193220 false ,
194221 Collections .emptyMap (),
195222 false ,
223+ false ,
196224 false
197225 );
198226 }
@@ -451,7 +479,11 @@ protected BytesRef toBytesRef(Object v) {
451479 @ Override
452480 public BlockLoader blockLoader (BlockLoaderContext blContext ) {
453481 if (textFieldType .isSyntheticSource ()) {
454- return new BytesFromMixedStringsBytesRefBlockLoader (storedFieldNameForSyntheticSource ());
482+ if (storedFieldInBinaryFormat ) {
483+ return new BlockStoredFieldsReader .BytesFromBytesRefsBlockLoader (storedFieldNameForSyntheticSource ());
484+ } else {
485+ return new BytesFromMixedStringsBytesRefBlockLoader (storedFieldNameForSyntheticSource ());
486+ }
455487 }
456488 SourceValueFetcher fetcher = SourceValueFetcher .toString (blContext .sourcePaths (name ()));
457489 // MatchOnlyText never has norms, so we have to use the field names field
@@ -502,6 +534,7 @@ private String storedFieldNameForSyntheticSource() {
502534 private final boolean storeSource ;
503535 private final FieldType fieldType ;
504536 private final boolean withinMultiField ;
537+ private final boolean storedFieldInBinaryFormat ;
505538
506539 private MatchOnlyTextFieldMapper (
507540 String simpleName ,
@@ -521,6 +554,7 @@ private MatchOnlyTextFieldMapper(
521554 this .positionIncrementGap = builder .analyzers .positionIncrementGap .getValue ();
522555 this .storeSource = storeSource ;
523556 this .withinMultiField = builder .withinMultiField ;
557+ this .storedFieldInBinaryFormat = builder .storedFieldInBinaryFormat ;
524558 }
525559
526560 @ Override
@@ -530,7 +564,7 @@ public Map<String, NamedAnalyzer> indexAnalyzers() {
530564
531565 @ Override
532566 public FieldMapper .Builder getMergeBuilder () {
533- return new Builder (leafName (), indexCreatedVersion , indexAnalyzers , withinMultiField ).init (this );
567+ return new Builder (leafName (), indexCreatedVersion , indexAnalyzers , withinMultiField , storedFieldInBinaryFormat ).init (this );
534568 }
535569
536570 @ Override
@@ -547,8 +581,12 @@ protected void parseCreateField(DocumentParserContext context) throws IOExceptio
547581 context .addToFieldNames (fieldType ().name ());
548582
549583 if (storeSource ) {
550- final var bytesRef = new BytesRef (utfBytes .bytes (), utfBytes .offset (), utfBytes .length ());
551- context .doc ().add (new StoredField (fieldType ().storedFieldNameForSyntheticSource (), bytesRef ));
584+ if (storedFieldInBinaryFormat ) {
585+ final var bytesRef = new BytesRef (utfBytes .bytes (), utfBytes .offset (), utfBytes .length ());
586+ context .doc ().add (new StoredField (fieldType ().storedFieldNameForSyntheticSource (), bytesRef ));
587+ } else {
588+ context .doc ().add (new StoredField (fieldType ().storedFieldNameForSyntheticSource (), value .string ()));
589+ }
552590 }
553591 }
554592
0 commit comments