2727import org .elasticsearch .core .Booleans ;
2828import org .elasticsearch .core .Nullable ;
2929import org .elasticsearch .index .IndexVersion ;
30+ import org .elasticsearch .index .IndexVersions ;
3031import org .elasticsearch .index .analysis .NamedAnalyzer ;
3132import org .elasticsearch .index .fielddata .FieldDataContext ;
3233import org .elasticsearch .index .fielddata .IndexFieldData ;
4748
4849import java .io .IOException ;
4950import java .time .ZoneId ;
51+ import java .util .ArrayList ;
5052import java .util .Collection ;
5153import java .util .Collections ;
5254import java .util .HashSet ;
5557import java .util .Objects ;
5658import java .util .Set ;
5759
60+ import static org .elasticsearch .index .mapper .FieldArrayContext .getOffsetsFieldName ;
61+
5862/**
5963 * A field mapper for boolean fields.
6064 */
@@ -99,9 +103,17 @@ public static final class Builder extends FieldMapper.DimensionBuilder {
99103
100104 private final IndexVersion indexCreatedVersion ;
101105
106+ private final SourceKeepMode indexSourceKeepMode ;
107+
102108 private final Parameter <Boolean > dimension ;
103109
104- public Builder (String name , ScriptCompiler scriptCompiler , boolean ignoreMalformedByDefault , IndexVersion indexCreatedVersion ) {
110+ public Builder (
111+ String name ,
112+ ScriptCompiler scriptCompiler ,
113+ boolean ignoreMalformedByDefault ,
114+ IndexVersion indexCreatedVersion ,
115+ SourceKeepMode indexSourceKeepMode
116+ ) {
105117 super (name );
106118 this .scriptCompiler = Objects .requireNonNull (scriptCompiler );
107119 this .indexCreatedVersion = Objects .requireNonNull (indexCreatedVersion );
@@ -126,6 +138,8 @@ public Builder(String name, ScriptCompiler scriptCompiler, boolean ignoreMalform
126138 );
127139 }
128140 });
141+
142+ this .indexSourceKeepMode = indexSourceKeepMode ;
129143 }
130144
131145 public Builder dimension (boolean dimension ) {
@@ -165,7 +179,23 @@ public BooleanFieldMapper build(MapperBuilderContext context) {
165179 );
166180 hasScript = script .get () != null ;
167181 onScriptError = onScriptErrorParam .getValue ();
168- return new BooleanFieldMapper (leafName (), ft , builderParams (this , context ), context .isSourceSynthetic (), this );
182+ String offsetsFieldName = getOffsetsFieldName (
183+ context ,
184+ indexSourceKeepMode ,
185+ docValues .getValue (),
186+ stored .getValue (),
187+ this ,
188+ indexCreatedVersion ,
189+ IndexVersions .SYNTHETIC_SOURCE_STORE_ARRAYS_NATIVELY_BOOLEAN
190+ );
191+ return new BooleanFieldMapper (
192+ leafName (),
193+ ft ,
194+ builderParams (this , context ),
195+ context .isSourceSynthetic (),
196+ this ,
197+ offsetsFieldName
198+ );
169199 }
170200
171201 private FieldValues <Boolean > scriptValues () {
@@ -182,7 +212,13 @@ private FieldValues<Boolean> scriptValues() {
182212 }
183213
184214 public static final TypeParser PARSER = createTypeParserWithLegacySupport (
185- (n , c ) -> new Builder (n , c .scriptCompiler (), IGNORE_MALFORMED_SETTING .get (c .getSettings ()), c .indexVersionCreated ())
215+ (n , c ) -> new Builder (
216+ n ,
217+ c .scriptCompiler (),
218+ IGNORE_MALFORMED_SETTING .get (c .getSettings ()),
219+ c .indexVersionCreated (),
220+ c .getIndexSettings ().sourceKeepMode ()
221+ )
186222 );
187223
188224 public static final class BooleanFieldType extends TermBasedFieldType {
@@ -484,12 +520,16 @@ public Query rangeQuery(
484520
485521 private final boolean storeMalformedFields ;
486522
523+ private final String offsetsFieldName ;
524+ private final SourceKeepMode indexSourceKeepMode ;
525+
487526 protected BooleanFieldMapper (
488527 String simpleName ,
489528 MappedFieldType mappedFieldType ,
490529 BuilderParams builderParams ,
491530 boolean storeMalformedFields ,
492- Builder builder
531+ Builder builder ,
532+ String offsetsFieldName
493533 ) {
494534 super (simpleName , mappedFieldType , builderParams );
495535 this .nullValue = builder .nullValue .getValue ();
@@ -503,6 +543,8 @@ protected BooleanFieldMapper(
503543 this .ignoreMalformed = builder .ignoreMalformed .getValue ();
504544 this .ignoreMalformedByDefault = builder .ignoreMalformed .getDefaultValue ().value ();
505545 this .storeMalformedFields = storeMalformedFields ;
546+ this .offsetsFieldName = offsetsFieldName ;
547+ this .indexSourceKeepMode = builder .indexSourceKeepMode ;
506548 }
507549
508550 @ Override
@@ -515,6 +557,11 @@ public BooleanFieldType fieldType() {
515557 return (BooleanFieldType ) super .fieldType ();
516558 }
517559
560+ @ Override
561+ public String getOffsetFieldName () {
562+ return offsetsFieldName ;
563+ }
564+
518565 @ Override
519566 protected void parseCreateField (DocumentParserContext context ) throws IOException {
520567 if (indexed == false && stored == false && hasDocValues == false ) {
@@ -537,12 +584,20 @@ protected void parseCreateField(DocumentParserContext context) throws IOExceptio
537584 // Save a copy of the field so synthetic source can load it
538585 context .doc ().add (IgnoreMalformedStoredValues .storedField (fullPath (), context .parser ()));
539586 }
587+ return ;
540588 } else {
541589 throw e ;
542590 }
543591 }
544592 }
545593 indexValue (context , value );
594+ if (offsetsFieldName != null && context .isImmediateParentAnArray () && context .canAddIgnoredField ()) {
595+ if (value != null ) {
596+ context .getOffSetContext ().recordOffset (offsetsFieldName , value );
597+ } else {
598+ context .getOffSetContext ().recordNull (offsetsFieldName );
599+ }
600+ }
546601 }
547602
548603 private void indexValue (DocumentParserContext context , Boolean value ) {
@@ -578,8 +633,9 @@ protected void indexScriptValues(
578633
579634 @ Override
580635 public FieldMapper .Builder getMergeBuilder () {
581- return new Builder (leafName (), scriptCompiler , ignoreMalformedByDefault , indexCreatedVersion ).dimension (fieldType ().isDimension ())
582- .init (this );
636+ return new Builder (leafName (), scriptCompiler , ignoreMalformedByDefault , indexCreatedVersion , indexSourceKeepMode ).dimension (
637+ fieldType ().isDimension ()
638+ ).init (this );
583639 }
584640
585641 @ Override
@@ -601,17 +657,34 @@ protected String contentType() {
601657 return CONTENT_TYPE ;
602658 }
603659
660+ private SourceLoader .SyntheticFieldLoader docValuesSyntheticFieldLoader () {
661+ if (offsetsFieldName != null ) {
662+ var layers = new ArrayList <CompositeSyntheticFieldLoader .Layer >();
663+ layers .add (
664+ new SortedNumericWithOffsetsDocValuesSyntheticFieldLoaderLayer (
665+ fullPath (),
666+ offsetsFieldName ,
667+ (b , value ) -> b .value (value == 1 )
668+ )
669+ );
670+ if (ignoreMalformed .value ()) {
671+ layers .add (new CompositeSyntheticFieldLoader .MalformedValuesLayer (fullPath ()));
672+ }
673+ return new CompositeSyntheticFieldLoader (leafName (), fullPath (), layers );
674+ } else {
675+ return new SortedNumericDocValuesSyntheticFieldLoader (fullPath (), leafName (), ignoreMalformed .value ()) {
676+ @ Override
677+ protected void writeValue (XContentBuilder b , long value ) throws IOException {
678+ b .value (value == 1 );
679+ }
680+ };
681+ }
682+ }
683+
604684 @ Override
605685 protected SyntheticSourceSupport syntheticSourceSupport () {
606686 if (hasDocValues ) {
607- return new SyntheticSourceSupport .Native (
608- () -> new SortedNumericDocValuesSyntheticFieldLoader (fullPath (), leafName (), ignoreMalformed .value ()) {
609- @ Override
610- protected void writeValue (XContentBuilder b , long value ) throws IOException {
611- b .value (value == 1 );
612- }
613- }
614- );
687+ return new SyntheticSourceSupport .Native (this ::docValuesSyntheticFieldLoader );
615688 }
616689
617690 return super .syntheticSourceSupport ();
0 commit comments