3434import org .elasticsearch .index .mapper .FieldMapper ;
3535import org .elasticsearch .index .mapper .MappedFieldType ;
3636import org .elasticsearch .index .mapper .MapperBuilderContext ;
37- import org .elasticsearch .index .mapper .MapperParsingException ;
3837import org .elasticsearch .index .mapper .MappingParserContext ;
3938import org .elasticsearch .index .mapper .SourceLoader ;
4039import org .elasticsearch .index .mapper .SourceValueFetcher ;
4342import org .elasticsearch .index .query .SearchExecutionContext ;
4443import org .elasticsearch .search .fetch .StoredFieldsSpec ;
4544import org .elasticsearch .search .lookup .Source ;
45+ import org .elasticsearch .xcontent .ConstructingObjectParser ;
46+ import org .elasticsearch .xcontent .DeprecationHandler ;
47+ import org .elasticsearch .xcontent .NamedXContentRegistry ;
48+ import org .elasticsearch .xcontent .ParseField ;
4649import org .elasticsearch .xcontent .ToXContent ;
4750import org .elasticsearch .xcontent .XContentBuilder ;
51+ import org .elasticsearch .xcontent .XContentParser ;
4852import org .elasticsearch .xcontent .XContentParser .Token ;
53+ import org .elasticsearch .xcontent .XContentType ;
54+ import org .elasticsearch .xcontent .support .MapXContentParser ;
4955
5056import java .io .IOException ;
5157import java .io .UncheckedIOException ;
5662import java .util .stream .Stream ;
5763
5864import static org .elasticsearch .index .query .AbstractQueryBuilder .DEFAULT_BOOST ;
65+ import static org .elasticsearch .xcontent .ConstructingObjectParser .optionalConstructorArg ;
5966
6067/**
6168 * A {@link FieldMapper} that exposes Lucene's {@link FeatureField} as a sparse
@@ -85,23 +92,22 @@ private static SparseVectorFieldMapper toType(FieldMapper in) {
8592 public static class Builder extends FieldMapper .Builder {
8693 private final Parameter <Boolean > stored = Parameter .storeParam (m -> toType (m ).fieldType ().isStored (), false );
8794 private final Parameter <Map <String , String >> meta = Parameter .metaParam ();
88- private final Parameter <IndexOptions > indexOptions ;
95+ private final Parameter <IndexOptions > indexOptions = new Parameter <>(
96+ SPARSE_VECTOR_INDEX_OPTIONS ,
97+ true ,
98+ () -> null ,
99+ (n , c , o ) -> parseIndexOptions (c , o ),
100+ m -> toType (m ).fieldType ().indexOptions ,
101+ (b , n , v ) -> {
102+ if (v != null ) {
103+ b .field (n , v );
104+ }
105+ },
106+ Objects ::toString
107+ );;
89108
90109 public Builder (String name ) {
91110 super (name );
92- this .indexOptions = new Parameter <>(
93- SPARSE_VECTOR_INDEX_OPTIONS ,
94- true ,
95- () -> null ,
96- (n , c , o ) -> parseIndexOptions (c , o ),
97- m -> toType (m ).fieldType ().indexOptions ,
98- (b , n , v ) -> {
99- if (v != null ) {
100- b .field (n , v );
101- }
102- },
103- Objects ::toString
104- );
105111 }
106112
107113 public Builder setStored (boolean value ) {
@@ -128,21 +134,35 @@ public IndexOptions getIndexOptions() {
128134 return fieldType ().getIndexOptions ();
129135 }
130136
137+ private static final ConstructingObjectParser <IndexOptions , Void > INDEX_OPTIONS_PARSER = new ConstructingObjectParser <>(
138+ SPARSE_VECTOR_INDEX_OPTIONS ,
139+ args -> new IndexOptions ((Boolean ) args [0 ], (TokenPruningConfig ) args [1 ])
140+ );
141+
142+ static {
143+ INDEX_OPTIONS_PARSER .declareBoolean (optionalConstructorArg (), IndexOptions .PRUNE_FIELD_NAME );
144+ INDEX_OPTIONS_PARSER .declareObject (optionalConstructorArg (), TokenPruningConfig .PARSER , IndexOptions .PRUNING_CONFIG_FIELD_NAME );
145+ }
146+
131147 private static SparseVectorFieldMapper .IndexOptions parseIndexOptions (MappingParserContext context , Object propNode ) {
132148 if (propNode == null ) {
133149 return null ;
134150 }
135151
136152 Map <String , Object > indexOptionsMap = XContentMapValues .nodeMapValue (propNode , SPARSE_VECTOR_INDEX_OPTIONS );
137153
138- Boolean prune = IndexOptions .parseIndexOptionsPruneValue (indexOptionsMap );
139- TokenPruningConfig pruningConfig = IndexOptions .parseIndexOptionsPruningConfig (prune , indexOptionsMap );
154+ XContentParser parser = new MapXContentParser (
155+ NamedXContentRegistry .EMPTY ,
156+ DeprecationHandler .IGNORE_DEPRECATIONS ,
157+ indexOptionsMap ,
158+ XContentType .JSON
159+ );
140160
141- if (prune == null && pruningConfig == null ) {
142- return null ;
161+ try {
162+ return INDEX_OPTIONS_PARSER .parse (parser , null );
163+ } catch (IOException e ) {
164+ throw new UncheckedIOException (e );
143165 }
144-
145- return new SparseVectorFieldMapper .IndexOptions (prune , pruningConfig );
146166 }
147167
148168 public static final TypeParser PARSER = new TypeParser ((n , c ) -> {
@@ -427,13 +447,25 @@ public void reset() {
427447 }
428448
429449 public static class IndexOptions implements ToXContent {
430- public static final String PRUNE_FIELD_NAME = "prune" ;
431- public static final String PRUNING_CONFIG_FIELD_NAME = "pruning_config" ;
450+ public static final ParseField PRUNE_FIELD_NAME = new ParseField ( "prune" ) ;
451+ public static final ParseField PRUNING_CONFIG_FIELD_NAME = new ParseField ( "pruning_config" ) ;
432452
433453 final Boolean prune ;
434454 final TokenPruningConfig pruningConfig ;
435455
436456 IndexOptions (@ Nullable Boolean prune , @ Nullable TokenPruningConfig pruningConfig ) {
457+ if (pruningConfig != null && (prune == null || prune == false )) {
458+ throw new IllegalArgumentException (
459+ "["
460+ + SPARSE_VECTOR_INDEX_OPTIONS
461+ + "] field ["
462+ + PRUNING_CONFIG_FIELD_NAME .getPreferredName ()
463+ + "] should only be set if ["
464+ + PRUNE_FIELD_NAME .getPreferredName ()
465+ + "] is set to true"
466+ );
467+ }
468+
437469 this .prune = prune ;
438470 this .pruningConfig = pruningConfig ;
439471 }
@@ -470,18 +502,19 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws
470502 builder .startObject ();
471503
472504 if (prune != null ) {
473- builder .field (PRUNE_FIELD_NAME , prune );
505+ builder .field (PRUNE_FIELD_NAME . getPreferredName () , prune );
474506 }
475507 if (pruningConfig != null ) {
476- builder .field (PRUNING_CONFIG_FIELD_NAME , pruningConfig );
508+ builder .field (PRUNING_CONFIG_FIELD_NAME . getPreferredName () , pruningConfig );
477509 }
478510
479511 builder .endObject ();
480512 return builder ;
481513 }
482514
515+ /*
483516 public static Boolean parseIndexOptionsPruneValue(Map<String, Object> indexOptionsMap) {
484- Object shouldPrune = indexOptionsMap .get (IndexOptions .PRUNE_FIELD_NAME );
517+ Object shouldPrune = indexOptionsMap.get(IndexOptions.PRUNE_FIELD_NAME.getPreferredName() );
485518 if (shouldPrune == null) {
486519 return null;
487520 }
@@ -491,12 +524,14 @@ public static Boolean parseIndexOptionsPruneValue(Map<String, Object> indexOptio
491524 }
492525
493526 throw new MapperParsingException(
494- "[" + SPARSE_VECTOR_INDEX_OPTIONS + "] field [" + PRUNE_FIELD_NAME + "] should be true or false"
527+ "[" + SPARSE_VECTOR_INDEX_OPTIONS + "] field [" + PRUNE_FIELD_NAME.getPreferredName() + "] should be true or false"
495528 );
496529 }
530+ */
497531
532+ /*
498533 public static TokenPruningConfig parseIndexOptionsPruningConfig(Boolean prune, Map<String, Object> indexOptionsMap) {
499- Object pruningConfiguration = indexOptionsMap .get (IndexOptions .PRUNING_CONFIG_FIELD_NAME );
534+ Object pruningConfiguration = indexOptionsMap.get(IndexOptions.PRUNING_CONFIG_FIELD_NAME.getPreferredName() );
500535 if (pruningConfiguration == null) {
501536 return null;
502537 }
@@ -506,16 +541,20 @@ public static TokenPruningConfig parseIndexOptionsPruningConfig(Boolean prune, M
506541 "["
507542 + SPARSE_VECTOR_INDEX_OPTIONS
508543 + "] field ["
509- + PRUNING_CONFIG_FIELD_NAME
544+ + PRUNING_CONFIG_FIELD_NAME.getPreferredName()
510545 + "] should only be set if ["
511- + PRUNE_FIELD_NAME
546+ + PRUNE_FIELD_NAME.getPreferredName()
512547 + "] is set to true"
513548 );
514549 }
515550
516- Map <String , Object > pruningConfigurationMap = XContentMapValues .nodeMapValue (pruningConfiguration , PRUNING_CONFIG_FIELD_NAME );
551+ Map<String, Object> pruningConfigurationMap = XContentMapValues.nodeMapValue(
552+ pruningConfiguration,
553+ PRUNING_CONFIG_FIELD_NAME.getPreferredName()
554+ );
517555
518556 return TokenPruningConfig.parseFromMap(pruningConfigurationMap);
519557 }
558+ */
520559 }
521560}
0 commit comments