4040 * 
4141 * A limitation of this class is that all the ValuesSource's being refereenced must be of the same type. 
4242 */ 
43- public  abstract  class  MultiValuesSourceAggregationBuilder <VS   extends   ValuesSource ,  AB  extends  MultiValuesSourceAggregationBuilder <VS ,  AB >>
43+ public  abstract  class  MultiValuesSourceAggregationBuilder <AB  extends  MultiValuesSourceAggregationBuilder <AB >>
4444        extends  AbstractAggregationBuilder <AB > {
4545
4646
47-     public  abstract  static  class  LeafOnly <VS   extends   ValuesSource ,  AB  extends  MultiValuesSourceAggregationBuilder <VS ,  AB >>
48-             extends  MultiValuesSourceAggregationBuilder <VS ,  AB > {
47+     public  abstract  static  class  LeafOnly <AB  extends  MultiValuesSourceAggregationBuilder <AB >>
48+             extends  MultiValuesSourceAggregationBuilder <AB > {
4949
50-         protected  LeafOnly (String  name ,  ValueType   targetValueType ) {
51-             super (name ,  targetValueType );
50+         protected  LeafOnly (String  name ) {
51+             super (name );
5252        }
5353
54-         protected  LeafOnly (LeafOnly <VS ,  AB > clone , Builder  factoriesBuilder , Map <String , Object > metaData ) {
54+         protected  LeafOnly (LeafOnly <AB > clone , Builder  factoriesBuilder , Map <String , Object > metaData ) {
5555            super (clone , factoriesBuilder , metaData );
5656            if  (factoriesBuilder .count () > 0 ) {
5757                throw  new  AggregationInitializationException ("Aggregator ["  + name  + "] of type [" 
@@ -62,8 +62,8 @@ protected LeafOnly(LeafOnly<VS, AB> clone, Builder factoriesBuilder, Map<String,
6262        /** 
6363         * Read from a stream that does not serialize its targetValueType. This should be used by most subclasses. 
6464         */ 
65-         protected  LeafOnly (StreamInput  in ,  ValueType   targetValueType ) throws  IOException  {
66-             super (in ,  targetValueType );
65+         protected  LeafOnly (StreamInput  in ) throws  IOException  {
66+             super (in );
6767        }
6868
6969        @ Override 
@@ -76,30 +76,28 @@ public AB subAggregations(Builder subFactories) {
7676
7777
7878    private  Map <String , MultiValuesSourceFieldConfig > fields  = new  HashMap <>();
79-     private  final  ValueType  targetValueType ;
80-     private  ValueType  valueType  = null ;
79+     private  ValueType  userValueTypeHint  = null ;
8180    private  String  format  = null ;
8281
83-     protected  MultiValuesSourceAggregationBuilder (String  name ,  ValueType   targetValueType ) {
82+     protected  MultiValuesSourceAggregationBuilder (String  name ) {
8483        super (name );
85-         this .targetValueType  = targetValueType ;
8684    }
8785
88-     protected  MultiValuesSourceAggregationBuilder (MultiValuesSourceAggregationBuilder <VS ,  AB > clone ,
86+     protected  MultiValuesSourceAggregationBuilder (MultiValuesSourceAggregationBuilder <AB > clone ,
8987                                                  Builder  factoriesBuilder , Map <String , Object > metaData ) {
9088        super (clone , factoriesBuilder , metaData );
9189
9290        this .fields  = new  HashMap <>(clone .fields );
93-         this .targetValueType  = clone .targetValueType ;
94-         this .valueType  = clone .valueType ;
91+         this .userValueTypeHint  = clone .userValueTypeHint ;
9592        this .format  = clone .format ;
9693    }
9794
98-     protected  MultiValuesSourceAggregationBuilder (StreamInput  in , ValueType  targetValueType )
95+     /** 
96+      * Read from a stream. 
97+      */ 
98+     protected  MultiValuesSourceAggregationBuilder (StreamInput  in )
9999        throws  IOException  {
100100        super (in );
101-         assert  false  == serializeTargetValueType () : "Wrong read constructor called for subclass that provides its targetValueType" ;
102-         this .targetValueType  = targetValueType ;
103101        read (in );
104102    }
105103
@@ -109,17 +107,14 @@ protected MultiValuesSourceAggregationBuilder(StreamInput in, ValueType targetVa
109107    @ SuppressWarnings ("unchecked" )
110108    private  void  read (StreamInput  in ) throws  IOException  {
111109        fields  = in .readMap (StreamInput ::readString , MultiValuesSourceFieldConfig ::new );
112-         valueType  = in .readOptionalWriteable (ValueType ::readFromStream );
110+         userValueTypeHint  = in .readOptionalWriteable (ValueType ::readFromStream );
113111        format  = in .readOptionalString ();
114112    }
115113
116114    @ Override 
117115    protected  final  void  doWriteTo (StreamOutput  out ) throws  IOException  {
118-         if  (serializeTargetValueType ()) {
119-             out .writeOptionalWriteable (targetValueType );
120-         }
121116        out .writeMap (fields , StreamOutput ::writeString , (o , value ) -> value .writeTo (o ));
122-         out .writeOptionalWriteable (valueType );
117+         out .writeOptionalWriteable (userValueTypeHint );
123118        out .writeOptionalString (format );
124119        innerWriteTo (out );
125120    }
@@ -142,11 +137,11 @@ protected AB field(String propertyName, MultiValuesSourceFieldConfig config) {
142137     * Sets the {@link ValueType} for the value produced by this aggregation 
143138     */ 
144139    @ SuppressWarnings ("unchecked" )
145-     public  AB  valueType (ValueType  valueType ) {
140+     public  AB  userValueTypeHint (ValueType  valueType ) {
146141        if  (valueType  == null ) {
147-             throw  new  IllegalArgumentException ("[valueType ] must not be null: ["  + name  + "]" );
142+             throw  new  IllegalArgumentException ("[userValueTypeHint ] must not be null: ["  + name  + "]" );
148143        }
149-         this .valueType  = valueType ;
144+         this .userValueTypeHint  = valueType ;
150145        return  (AB ) this ;
151146    }
152147
@@ -162,25 +157,34 @@ public AB format(String format) {
162157        return  (AB ) this ;
163158    }
164159
165-     @ Override 
166-     protected  final  MultiValuesSourceAggregatorFactory <VS > doBuild (QueryShardContext  queryShardContext , AggregatorFactory  parent ,
167-                                                                    Builder  subFactoriesBuilder ) throws  IOException  {
168-         ValueType  finalValueType  = this .valueType  != null  ? this .valueType  : targetValueType ;
160+     /** 
161+      * Aggregations should use this method to define a {@link ValuesSourceType} of last resort.  This will only be used when the resolver 
162+      * can't find a field and the user hasn't provided a value type hint. 
163+      * 
164+      * @return The CoreValuesSourceType we expect this script to yield. 
165+      */ 
166+     protected  abstract  ValuesSourceType  defaultValueSourceType ();
169167
168+     @ Override 
169+     protected  final  MultiValuesSourceAggregatorFactory  doBuild (QueryShardContext  queryShardContext , AggregatorFactory  parent ,
170+                                                                Builder  subFactoriesBuilder ) throws  IOException  {
170171        Map <String , ValuesSourceConfig > configs  = new  HashMap <>(fields .size ());
171172        fields .forEach ((key , value ) -> {
172-             ValuesSourceConfig  config  = ValuesSourceConfig .resolve (queryShardContext , finalValueType ,
173-                 value .getFieldName (), value .getScript (), value .getMissing (), value .getTimeZone (), format , getType ());
173+             ValuesSourceConfig  config  = ValuesSourceConfig .resolve (queryShardContext , userValueTypeHint ,
174+                 value .getFieldName (), value .getScript (), value .getMissing (), value .getTimeZone (), format , defaultValueSourceType (),
175+                 getType ());
174176            configs .put (key , config );
175177        });
176-         DocValueFormat  docValueFormat  = resolveFormat (format , finalValueType );
178+         DocValueFormat  docValueFormat  = resolveFormat (format , userValueTypeHint ,  defaultValueSourceType () );
177179        return  innerBuild (queryShardContext , configs , docValueFormat , parent , subFactoriesBuilder );
178180    }
179181
180182
181-     private  static  DocValueFormat  resolveFormat (@ Nullable  String  format , @ Nullable  ValueType  valueType ) {
183+     private  static  DocValueFormat  resolveFormat (@ Nullable  String  format , @ Nullable  ValueType  valueType ,
184+                                                 ValuesSourceType  defaultValuesSourceType ) {
182185        if  (valueType  == null ) {
183-             return  DocValueFormat .RAW ; // we can't figure it out 
186+             // If the user didn't send a hint, all we can do is fall back to the default 
187+             return  defaultValuesSourceType .getFormatter (format , null );
184188        }
185189        DocValueFormat  valueFormat  = valueType .defaultFormat ;
186190        if  (valueFormat  instanceof  DocValueFormat .Decimal  && format  != null ) {
@@ -189,19 +193,11 @@ private static DocValueFormat resolveFormat(@Nullable String format, @Nullable V
189193        return  valueFormat ;
190194    }
191195
192-     protected  abstract  MultiValuesSourceAggregatorFactory <VS > innerBuild (QueryShardContext  queryShardContext ,
193-                                                                          Map <String , ValuesSourceConfig > configs ,
194-                                                                          DocValueFormat  format , AggregatorFactory  parent ,
195-                                                                          Builder  subFactoriesBuilder ) throws  IOException ;
196- 
196+     protected  abstract  MultiValuesSourceAggregatorFactory  innerBuild (QueryShardContext  queryShardContext ,
197+                                                                      Map <String , ValuesSourceConfig > configs ,
198+                                                                      DocValueFormat  format , AggregatorFactory  parent ,
199+                                                                      Builder  subFactoriesBuilder ) throws  IOException ;
197200
198-     /** 
199-      * Should this builder serialize its targetValueType? Defaults to false. All subclasses that override this to true 
200-      * should use the three argument read constructor rather than the four argument version. 
201-      */ 
202-     protected  boolean  serializeTargetValueType () {
203-         return  false ;
204-     }
205201
206202    @ Override 
207203    public  final  XContentBuilder  internalXContent (XContentBuilder  builder , Params  params ) throws  IOException  {
@@ -214,8 +210,8 @@ public final XContentBuilder internalXContent(XContentBuilder builder, Params pa
214210        if  (format  != null ) {
215211            builder .field (CommonFields .FORMAT .getPreferredName (), format );
216212        }
217-         if  (valueType  != null ) {
218-             builder .field (CommonFields .VALUE_TYPE .getPreferredName (), valueType .getPreferredName ());
213+         if  (userValueTypeHint  != null ) {
214+             builder .field (CommonFields .VALUE_TYPE .getPreferredName (), userValueTypeHint .getPreferredName ());
219215        }
220216        doXContentBody (builder , params );
221217        builder .endObject ();
@@ -226,7 +222,7 @@ public final XContentBuilder internalXContent(XContentBuilder builder, Params pa
226222
227223    @ Override 
228224    public  int  hashCode () {
229-         return  Objects .hash (super .hashCode (), fields , format , targetValueType ,  valueType );
225+         return  Objects .hash (super .hashCode (), fields , format , userValueTypeHint );
230226    }
231227
232228
@@ -239,6 +235,6 @@ public boolean equals(Object obj) {
239235        MultiValuesSourceAggregationBuilder  other  = (MultiValuesSourceAggregationBuilder ) obj ;
240236        return  Objects .equals (this .fields , other .fields )
241237            && Objects .equals (this .format , other .format )
242-             && Objects .equals (this .valueType , other .valueType );
238+             && Objects .equals (this .userValueTypeHint , other .userValueTypeHint );
243239    }
244240}
0 commit comments