Files
2019-05-13 20:38:06 +03:00

227 lines
4.7 KiB
Go

package elastigo
import "encoding/json"
func Aggregate(name string) *AggregateDsl {
return &AggregateDsl{Name: name}
}
type AggregateDsl struct {
Name string
TypeName string
Type interface{}
Filters *FilterWrap `json:"filters,omitempty"`
AggregatesVal map[string]*AggregateDsl `json:"aggregations,omitempty"`
}
type FieldAggregate struct {
Field string `json:"field"`
Size *int `json:"size,omitempty"`
}
/**
* Aggregates accepts n "sub-aggregates" to be applied to this aggregate
*
* agg := Aggregate("user").Term("user_id")
* agg.Aggregates(
* Aggregate("total_spent").Sum("price"),
* Aggregate("total_saved").Sum("discount"),
* )
*/
func (d *AggregateDsl) Aggregates(aggs ...*AggregateDsl) *AggregateDsl {
if len(aggs) < 1 {
return d
}
if len(d.AggregatesVal) == 0 {
d.AggregatesVal = make(map[string]*AggregateDsl)
}
for _, agg := range aggs {
d.AggregatesVal[agg.Name] = agg
}
return d
}
func (d *AggregateDsl) Min(field string) *AggregateDsl {
d.Type = FieldAggregate{Field: field}
d.TypeName = "min"
return d
}
func (d *AggregateDsl) Max(field string) *AggregateDsl {
d.Type = FieldAggregate{Field: field}
d.TypeName = "max"
return d
}
func (d *AggregateDsl) Sum(field string) *AggregateDsl {
d.Type = FieldAggregate{Field: field}
d.TypeName = "sum"
return d
}
func (d *AggregateDsl) Avg(field string) *AggregateDsl {
d.Type = FieldAggregate{Field: field}
d.TypeName = "avg"
return d
}
func (d *AggregateDsl) Stats(field string) *AggregateDsl {
d.Type = FieldAggregate{Field: field}
d.TypeName = "stats"
return d
}
func (d *AggregateDsl) ExtendedStats(field string) *AggregateDsl {
d.Type = FieldAggregate{Field: field}
d.TypeName = "extended_stats"
return d
}
func (d *AggregateDsl) ValueCount(field string) *AggregateDsl {
d.Type = FieldAggregate{Field: field}
d.TypeName = "value_count"
return d
}
func (d *AggregateDsl) Percentiles(field string) *AggregateDsl {
d.Type = FieldAggregate{Field: field}
d.TypeName = "percentiles"
return d
}
type Cardinality struct {
Field string `json:"field"`
PrecisionThreshold float64 `json:"precision_threshold,omitempty"`
Rehash bool `json:"rehash,omitempty"`
}
/**
* Cardinality(
* "field_name",
* true,
* 0,
* )
*/
func (d *AggregateDsl) Cardinality(field string, rehash bool, threshold int) *AggregateDsl {
c := Cardinality{Field: field}
// Only set if it's false, since the default is true
if !rehash {
c.Rehash = false
}
if threshold > 0 {
c.PrecisionThreshold = float64(threshold)
}
d.Type = c
d.TypeName = "cardinality"
return d
}
func (d *AggregateDsl) Global() *AggregateDsl {
d.Type = struct{}{}
d.TypeName = "global"
return d
}
func (d *AggregateDsl) Filter(filters ...interface{}) *AggregateDsl {
if len(filters) == 0 {
return d
}
if d.Filters == nil {
d.Filters = NewFilterWrap()
}
d.Filters.addFilters(filters)
return d
}
func (d *AggregateDsl) Missing(field string) *AggregateDsl {
d.Type = FieldAggregate{Field: field}
d.TypeName = "missing"
return d
}
func (d *AggregateDsl) Terms(field string) *AggregateDsl {
d.Type = FieldAggregate{Field: field}
d.TypeName = "terms"
return d
}
func (d *AggregateDsl) TermsWithSize(field string, size int) *AggregateDsl {
d.Type = FieldAggregate{Field: field, Size: &size}
d.TypeName = "terms"
return d
}
func (d *AggregateDsl) SignificantTerms(field string) *AggregateDsl {
d.Type = FieldAggregate{Field: field}
d.TypeName = "significant_terms"
return d
}
type Histogram struct {
Field string `json:"field"`
Interval float64 `json:"interval"`
}
func (d *AggregateDsl) Histogram(field string, interval int) *AggregateDsl {
d.Type = Histogram{
Field: field,
Interval: float64(interval),
}
d.TypeName = "histogram"
return d
}
type DateHistogram struct {
Field string `json:"field"`
Interval string `json:"interval"`
}
func (d *AggregateDsl) DateHistogram(field, interval string) *AggregateDsl {
d.Type = DateHistogram{
Field: field,
Interval: interval,
}
d.TypeName = "date_histogram"
return d
}
func (d *AggregateDsl) MarshalJSON() ([]byte, error) {
return json.Marshal(d.toMap())
}
func (d *AggregateDsl) toMap() map[string]interface{} {
root := map[string]interface{}{}
if d.Type != nil {
root[d.TypeName] = d.Type
}
aggregates := d.aggregatesMap()
if d.Filters != nil {
root["filter"] = d.Filters
}
if len(aggregates) > 0 {
root["aggregations"] = aggregates
}
return root
}
func (d *AggregateDsl) aggregatesMap() map[string]interface{} {
root := map[string]interface{}{}
if len(d.AggregatesVal) > 0 {
for _, agg := range d.AggregatesVal {
root[agg.Name] = agg.toMap()
}
}
return root
}