1919import org .elasticsearch .common .Explicit ;
2020import org .elasticsearch .common .io .stream .ByteArrayStreamInput ;
2121import org .elasticsearch .common .io .stream .BytesStreamOutput ;
22+ import org .elasticsearch .common .settings .Setting ;
2223import org .elasticsearch .common .util .BigArrays ;
2324import org .elasticsearch .index .fielddata .FieldDataContext ;
2425import org .elasticsearch .index .fielddata .FormattedDocValues ;
3738import org .elasticsearch .index .mapper .IndexType ;
3839import org .elasticsearch .index .mapper .MappedFieldType ;
3940import org .elasticsearch .index .mapper .MapperBuilderContext ;
41+ import org .elasticsearch .index .mapper .NumberFieldMapper ;
4042import org .elasticsearch .index .mapper .SourceLoader ;
4143import org .elasticsearch .index .mapper .SourceValueFetcher ;
4244import org .elasticsearch .index .mapper .ValueFetcher ;
6264 * Field Mapper for pre-aggregated histograms.
6365 */
6466public class HistogramFieldMapper extends FieldMapper {
67+
6568 public static final String CONTENT_TYPE = "histogram" ;
6669
70+ // use the same default as numbers
71+ private static final Setting <Boolean > COERCE_SETTING = NumberFieldMapper .COERCE_SETTING ;
72+
6773 private static HistogramFieldMapper toType (FieldMapper in ) {
6874 return (HistogramFieldMapper ) in ;
6975 }
@@ -72,20 +78,26 @@ public static class Builder extends FieldMapper.Builder {
7278
7379 private final Parameter <Map <String , String >> meta = Parameter .metaParam ();
7480 private final Parameter <Explicit <Boolean >> ignoreMalformed ;
81+ private final Parameter <Explicit <Boolean >> coerce ;
7582
76- public Builder (String name , boolean ignoreMalformedByDefault ) {
83+ public Builder (String name , boolean ignoreMalformedByDefault , boolean coerceByDefault ) {
7784 super (name );
7885 this .ignoreMalformed = Parameter .explicitBoolParam (
7986 "ignore_malformed" ,
8087 true ,
8188 m -> toType (m ).ignoreMalformed ,
8289 ignoreMalformedByDefault
8390 );
91+ this .coerce = Parameter .explicitBoolParam ("coerce" , true , m -> toType (m ).coerce , coerceByDefault );
8492 }
8593
8694 @ Override
8795 protected Parameter <?>[] getParameters () {
88- return new Parameter <?>[] { ignoreMalformed , meta };
96+ if (ExponentialHistogramParser .EXPONENTIAL_HISTOGRAM_FEATURE .isEnabled ()) {
97+ return new Parameter <?>[] { ignoreMalformed , coerce , meta };
98+ } else {
99+ return new Parameter <?>[] { ignoreMalformed , meta };
100+ }
89101 }
90102
91103 @ Override
@@ -100,32 +112,41 @@ public HistogramFieldMapper build(MapperBuilderContext context) {
100112 }
101113
102114 public static final TypeParser PARSER = new TypeParser (
103- (n , c ) -> new Builder (n , IGNORE_MALFORMED_SETTING .get (c .getSettings ())),
115+ (n , c ) -> new Builder (n , IGNORE_MALFORMED_SETTING .get (c .getSettings ()), COERCE_SETTING . get ( c . getSettings ()) ),
104116 notInMultiFields (CONTENT_TYPE )
105117 );
106118
107119 private final Explicit <Boolean > ignoreMalformed ;
108120 private final boolean ignoreMalformedByDefault ;
109121
122+ private final Explicit <Boolean > coerce ;
123+ private final boolean coerceByDefault ;
124+
110125 public HistogramFieldMapper (String simpleName , MappedFieldType mappedFieldType , BuilderParams builderParams , Builder builder ) {
111126 super (simpleName , mappedFieldType , builderParams );
112127 this .ignoreMalformed = builder .ignoreMalformed .getValue ();
113128 this .ignoreMalformedByDefault = builder .ignoreMalformed .getDefaultValue ().value ();
129+ this .coerce = builder .coerce .getValue ();
130+ this .coerceByDefault = builder .coerce .getDefaultValue ().value ();
114131 }
115132
116133 @ Override
117134 public boolean ignoreMalformed () {
118135 return ignoreMalformed .value ();
119136 }
120137
138+ boolean coerce () {
139+ return coerce .value ();
140+ }
141+
121142 @ Override
122143 protected String contentType () {
123144 return CONTENT_TYPE ;
124145 }
125146
126147 @ Override
127148 public FieldMapper .Builder getMergeBuilder () {
128- return new Builder (leafName (), ignoreMalformedByDefault ).init (this );
149+ return new Builder (leafName (), ignoreMalformedByDefault , coerceByDefault ).init (this );
129150 }
130151
131152 @ Override
@@ -300,7 +321,20 @@ public void parse(DocumentParserContext context) throws IOException {
300321 subParser = new XContentSubParser (context .parser ());
301322 }
302323 subParser .nextToken ();
303- HistogramParser .ParsedHistogram parsedHistogram = HistogramParser .parse (fullPath (), subParser );
324+
325+ HistogramParser .ParsedHistogram parsedHistogram ;
326+ if (ExponentialHistogramParser .EXPONENTIAL_HISTOGRAM_FEATURE .isEnabled ()
327+ && coerce ()
328+ && subParser .currentToken () == XContentParser .Token .FIELD_NAME
329+ && ExponentialHistogramParser .isExponentialHistogramSubFieldName (subParser .currentName ())) {
330+ ExponentialHistogramParser .ParsedExponentialHistogram parsedExponential = ExponentialHistogramParser .parse (
331+ fullPath (),
332+ subParser
333+ );
334+ parsedHistogram = ParsedHistogramConverter .exponentialToTDigest (parsedExponential );
335+ } else {
336+ parsedHistogram = HistogramParser .parse (fullPath (), subParser );
337+ }
304338
305339 BytesStreamOutput streamOutput = new BytesStreamOutput ();
306340 for (int i = 0 ; i < parsedHistogram .values ().size (); i ++) {
@@ -358,7 +392,7 @@ public void parse(DocumentParserContext context) throws IOException {
358392 }
359393
360394 /** re-usable {@link HistogramValue} implementation */
361- private static class InternalHistogramValue extends HistogramValue {
395+ static class InternalHistogramValue extends HistogramValue {
362396 double value ;
363397 long count ;
364398 boolean isExhausted ;
0 commit comments