2828import org .elasticsearch .core .Nullable ;
2929import org .elasticsearch .features .NodeFeature ;
3030import org .elasticsearch .index .IndexVersion ;
31+ import org .elasticsearch .index .IndexVersions ;
3132import org .elasticsearch .index .analysis .NamedAnalyzer ;
3233import org .elasticsearch .index .fielddata .FieldDataContext ;
3334import org .elasticsearch .index .fielddata .IndexFieldData ;
4849
4950import java .io .IOException ;
5051import java .time .ZoneId ;
52+ import java .util .ArrayList ;
5153import java .util .Collection ;
5254import java .util .Collections ;
5355import java .util .HashSet ;
5658import java .util .Objects ;
5759import java .util .Set ;
5860
61+ import static org .elasticsearch .index .mapper .FieldArrayContext .getOffsetsFieldName ;
62+
5963/**
6064 * A field mapper for boolean fields.
6165 */
@@ -102,9 +106,17 @@ public static final class Builder extends FieldMapper.DimensionBuilder {
102106
103107 private final IndexVersion indexCreatedVersion ;
104108
109+ private final SourceKeepMode indexSourceKeepMode ;
110+
105111 private final Parameter <Boolean > dimension ;
106112
107- public Builder (String name , ScriptCompiler scriptCompiler , boolean ignoreMalformedByDefault , IndexVersion indexCreatedVersion ) {
113+ public Builder (
114+ String name ,
115+ ScriptCompiler scriptCompiler ,
116+ boolean ignoreMalformedByDefault ,
117+ IndexVersion indexCreatedVersion ,
118+ SourceKeepMode indexSourceKeepMode
119+ ) {
108120 super (name );
109121 this .scriptCompiler = Objects .requireNonNull (scriptCompiler );
110122 this .indexCreatedVersion = Objects .requireNonNull (indexCreatedVersion );
@@ -129,6 +141,8 @@ public Builder(String name, ScriptCompiler scriptCompiler, boolean ignoreMalform
129141 );
130142 }
131143 });
144+
145+ this .indexSourceKeepMode = indexSourceKeepMode ;
132146 }
133147
134148 public Builder dimension (boolean dimension ) {
@@ -168,7 +182,23 @@ public BooleanFieldMapper build(MapperBuilderContext context) {
168182 );
169183 hasScript = script .get () != null ;
170184 onScriptError = onScriptErrorParam .getValue ();
171- return new BooleanFieldMapper (leafName (), ft , builderParams (this , context ), context .isSourceSynthetic (), this );
185+ String offsetsFieldName = getOffsetsFieldName (
186+ context ,
187+ indexSourceKeepMode ,
188+ docValues .getValue (),
189+ stored .getValue (),
190+ this ,
191+ indexCreatedVersion ,
192+ IndexVersions .SYNTHETIC_SOURCE_STORE_ARRAYS_NATIVELY
193+ );
194+ return new BooleanFieldMapper (
195+ leafName (),
196+ ft ,
197+ builderParams (this , context ),
198+ context .isSourceSynthetic (),
199+ this ,
200+ offsetsFieldName
201+ );
172202 }
173203
174204 private FieldValues <Boolean > scriptValues () {
@@ -187,7 +217,13 @@ private FieldValues<Boolean> scriptValues() {
187217 private static final IndexVersion MINIMUM_COMPATIBILITY_VERSION = IndexVersion .fromId (5000099 );
188218
189219 public static final TypeParser PARSER = new TypeParser (
190- (n , c ) -> new Builder (n , c .scriptCompiler (), IGNORE_MALFORMED_SETTING .get (c .getSettings ()), c .indexVersionCreated ()),
220+ (n , c ) -> new Builder (
221+ n ,
222+ c .scriptCompiler (),
223+ IGNORE_MALFORMED_SETTING .get (c .getSettings ()),
224+ c .indexVersionCreated (),
225+ c .getIndexSettings ().sourceKeepMode ()
226+ ),
191227 MINIMUM_COMPATIBILITY_VERSION
192228 );
193229
@@ -490,12 +526,16 @@ public Query rangeQuery(
490526
491527 private final boolean storeMalformedFields ;
492528
529+ private final String offsetsFieldName ;
530+ private final SourceKeepMode indexSourceKeepMode ;
531+
493532 protected BooleanFieldMapper (
494533 String simpleName ,
495534 MappedFieldType mappedFieldType ,
496535 BuilderParams builderParams ,
497536 boolean storeMalformedFields ,
498- Builder builder
537+ Builder builder ,
538+ String offsetsFieldName
499539 ) {
500540 super (simpleName , mappedFieldType , builderParams );
501541 this .nullValue = builder .nullValue .getValue ();
@@ -509,6 +549,8 @@ protected BooleanFieldMapper(
509549 this .ignoreMalformed = builder .ignoreMalformed .getValue ();
510550 this .ignoreMalformedByDefault = builder .ignoreMalformed .getDefaultValue ().value ();
511551 this .storeMalformedFields = storeMalformedFields ;
552+ this .offsetsFieldName = offsetsFieldName ;
553+ this .indexSourceKeepMode = builder .indexSourceKeepMode ;
512554 }
513555
514556 @ Override
@@ -521,6 +563,11 @@ public BooleanFieldType fieldType() {
521563 return (BooleanFieldType ) super .fieldType ();
522564 }
523565
566+ @ Override
567+ public String getOffsetFieldName () {
568+ return offsetsFieldName ;
569+ }
570+
524571 @ Override
525572 protected void parseCreateField (DocumentParserContext context ) throws IOException {
526573 if (indexed == false && stored == false && hasDocValues == false ) {
@@ -543,12 +590,20 @@ protected void parseCreateField(DocumentParserContext context) throws IOExceptio
543590 // Save a copy of the field so synthetic source can load it
544591 context .doc ().add (IgnoreMalformedStoredValues .storedField (fullPath (), context .parser ()));
545592 }
593+ return ;
546594 } else {
547595 throw e ;
548596 }
549597 }
550598 }
551599 indexValue (context , value );
600+ if (offsetsFieldName != null && context .isImmediateParentAnArray () && context .canAddIgnoredField ()) {
601+ if (value != null ) {
602+ context .getOffSetContext ().recordOffset (offsetsFieldName , value );
603+ } else {
604+ context .getOffSetContext ().recordNull (offsetsFieldName );
605+ }
606+ }
552607 }
553608
554609 private void indexValue (DocumentParserContext context , Boolean value ) {
@@ -584,8 +639,9 @@ protected void indexScriptValues(
584639
585640 @ Override
586641 public FieldMapper .Builder getMergeBuilder () {
587- return new Builder (leafName (), scriptCompiler , ignoreMalformedByDefault , indexCreatedVersion ).dimension (fieldType ().isDimension ())
588- .init (this );
642+ return new Builder (leafName (), scriptCompiler , ignoreMalformedByDefault , indexCreatedVersion , indexSourceKeepMode ).dimension (
643+ fieldType ().isDimension ()
644+ ).init (this );
589645 }
590646
591647 @ Override
@@ -607,17 +663,34 @@ protected String contentType() {
607663 return CONTENT_TYPE ;
608664 }
609665
666+ private SourceLoader .SyntheticFieldLoader docValuesSyntheticFieldLoader () {
667+ if (offsetsFieldName != null ) {
668+ var layers = new ArrayList <CompositeSyntheticFieldLoader .Layer >();
669+ layers .add (
670+ new SortedNumericWithOffsetsDocValuesSyntheticFieldLoaderLayer (
671+ fullPath (),
672+ offsetsFieldName ,
673+ (b , value ) -> b .value (value == 1 )
674+ )
675+ );
676+ if (ignoreMalformed .value ()) {
677+ layers .add (new CompositeSyntheticFieldLoader .MalformedValuesLayer (fullPath ()));
678+ }
679+ return new CompositeSyntheticFieldLoader (leafName (), fullPath (), layers );
680+ } else {
681+ return new SortedNumericDocValuesSyntheticFieldLoader (fullPath (), leafName (), ignoreMalformed .value ()) {
682+ @ Override
683+ protected void writeValue (XContentBuilder b , long value ) throws IOException {
684+ b .value (value == 1 );
685+ }
686+ };
687+ }
688+ }
689+
610690 @ Override
611691 protected SyntheticSourceSupport syntheticSourceSupport () {
612692 if (hasDocValues ) {
613- return new SyntheticSourceSupport .Native (
614- () -> new SortedNumericDocValuesSyntheticFieldLoader (fullPath (), leafName (), ignoreMalformed .value ()) {
615- @ Override
616- protected void writeValue (XContentBuilder b , long value ) throws IOException {
617- b .value (value == 1 );
618- }
619- }
620- );
693+ return new SyntheticSourceSupport .Native (this ::docValuesSyntheticFieldLoader );
621694 }
622695
623696 return super .syntheticSourceSupport ();
0 commit comments