1// Copyright 2012-present Oliver Eilhard. All rights reserved.
2// Use of this source code is governed by a MIT-license.
3// See http://olivere.mit-license.org/license.txt for details.
4
5package elastic
6
7// ExtendedExtendedStatsAggregation is a multi-value metrics aggregation that
8// computes stats over numeric values extracted from the aggregated documents.
9// These values can be extracted either from specific numeric fields
10// in the documents, or be generated by a provided script.
11// See: https://www.elastic.co/guide/en/elasticsearch/reference/5.2/search-aggregations-metrics-extendedstats-aggregation.html
12type ExtendedStatsAggregation struct {
13	field           string
14	script          *Script
15	format          string
16	subAggregations map[string]Aggregation
17	meta            map[string]interface{}
18}
19
20func NewExtendedStatsAggregation() *ExtendedStatsAggregation {
21	return &ExtendedStatsAggregation{
22		subAggregations: make(map[string]Aggregation),
23	}
24}
25
26func (a *ExtendedStatsAggregation) Field(field string) *ExtendedStatsAggregation {
27	a.field = field
28	return a
29}
30
31func (a *ExtendedStatsAggregation) Script(script *Script) *ExtendedStatsAggregation {
32	a.script = script
33	return a
34}
35
36func (a *ExtendedStatsAggregation) Format(format string) *ExtendedStatsAggregation {
37	a.format = format
38	return a
39}
40
41func (a *ExtendedStatsAggregation) SubAggregation(name string, subAggregation Aggregation) *ExtendedStatsAggregation {
42	a.subAggregations[name] = subAggregation
43	return a
44}
45
46// Meta sets the meta data to be included in the aggregation response.
47func (a *ExtendedStatsAggregation) Meta(metaData map[string]interface{}) *ExtendedStatsAggregation {
48	a.meta = metaData
49	return a
50}
51
52func (a *ExtendedStatsAggregation) Source() (interface{}, error) {
53	// Example:
54	//	{
55	//    "aggs" : {
56	//      "grades_stats" : { "extended_stats" : { "field" : "grade" } }
57	//    }
58	//	}
59	// This method returns only the { "extended_stats" : { "field" : "grade" } } part.
60
61	source := make(map[string]interface{})
62	opts := make(map[string]interface{})
63	source["extended_stats"] = opts
64
65	// ValuesSourceAggregationBuilder
66	if a.field != "" {
67		opts["field"] = a.field
68	}
69	if a.script != nil {
70		src, err := a.script.Source()
71		if err != nil {
72			return nil, err
73		}
74		opts["script"] = src
75	}
76	if a.format != "" {
77		opts["format"] = a.format
78	}
79
80	// AggregationBuilder (SubAggregations)
81	if len(a.subAggregations) > 0 {
82		aggsMap := make(map[string]interface{})
83		source["aggregations"] = aggsMap
84		for name, aggregate := range a.subAggregations {
85			src, err := aggregate.Source()
86			if err != nil {
87				return nil, err
88			}
89			aggsMap[name] = src
90		}
91	}
92
93	// Add Meta data if available
94	if len(a.meta) > 0 {
95		source["meta"] = a.meta
96	}
97
98	return source, nil
99}
100