466 lines
14 KiB
Go
466 lines
14 KiB
Go
package esquery
|
|
|
|
import "github.com/fatih/structs"
|
|
|
|
// BaseAgg contains several fields that are common for all aggregation types.
|
|
type BaseAgg struct {
|
|
name string
|
|
apiName string
|
|
*BaseAggParams `structs:",flatten"`
|
|
}
|
|
|
|
// BaseAggParams contains fields that are common to most metric-aggregation
|
|
// types.
|
|
type BaseAggParams struct {
|
|
// Field is the name of the field to aggregate on.
|
|
Field string `structs:"field"`
|
|
// Miss is a value to provide for documents that are missing a value for the
|
|
// field.
|
|
Miss interface{} `structs:"missing,omitempty"`
|
|
}
|
|
|
|
func newBaseAgg(apiName, name, field string) *BaseAgg {
|
|
return &BaseAgg{
|
|
name: name,
|
|
apiName: apiName,
|
|
BaseAggParams: &BaseAggParams{
|
|
Field: field,
|
|
},
|
|
}
|
|
}
|
|
|
|
// Name returns the name of the aggregation, allowing implementation of the
|
|
// Aggregation interface.
|
|
func (agg *BaseAgg) Name() string {
|
|
return agg.name
|
|
}
|
|
|
|
// Map returns a map representation of the aggregation, implementing the
|
|
// Mappable interface.
|
|
func (agg *BaseAgg) Map() map[string]interface{} {
|
|
return map[string]interface{}{
|
|
agg.apiName: structs.Map(agg.BaseAggParams),
|
|
}
|
|
}
|
|
|
|
// AvgAgg represents an aggregation of type "avg", as described in
|
|
// https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics-avg-aggregation.html
|
|
type AvgAgg struct {
|
|
*BaseAgg `structs:",flatten"`
|
|
}
|
|
|
|
// Avg creates an aggregation of type "avg", with the provided name and on the
|
|
// provided field.
|
|
func Avg(name, field string) *AvgAgg {
|
|
return &AvgAgg{
|
|
BaseAgg: newBaseAgg("avg", name, field),
|
|
}
|
|
}
|
|
|
|
// Missing sets the value to provide for documents missing a value for the
|
|
// selected field.
|
|
func (agg *AvgAgg) Missing(val interface{}) *AvgAgg {
|
|
agg.Miss = val
|
|
return agg
|
|
}
|
|
|
|
//----------------------------------------------------------------------------//
|
|
|
|
// WeightedAvgAgg represents an aggregation of type "weighted_avg", as described
|
|
// in https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics-weight-avg-aggregation.html
|
|
type WeightedAvgAgg struct {
|
|
name string
|
|
apiName string
|
|
|
|
// Val is the value component of the aggregation
|
|
Val *BaseAggParams `structs:"value"`
|
|
|
|
// Weig is the weight component of the aggregation
|
|
Weig *BaseAggParams `structs:"weight"`
|
|
}
|
|
|
|
// WeightedAvg creates a new aggregation of type "weighted_agg" with the
|
|
// provided name.
|
|
func WeightedAvg(name string) *WeightedAvgAgg {
|
|
return &WeightedAvgAgg{
|
|
name: name,
|
|
apiName: "weighted_avg",
|
|
}
|
|
}
|
|
|
|
// Name returns the name of the aggregation.
|
|
func (agg *WeightedAvgAgg) Name() string {
|
|
return agg.name
|
|
}
|
|
|
|
// Value sets the value field and optionally a value to use when records are
|
|
// missing a value for the field.
|
|
func (agg *WeightedAvgAgg) Value(field string, missing ...interface{}) *WeightedAvgAgg {
|
|
agg.Val = new(BaseAggParams)
|
|
agg.Val.Field = field
|
|
if len(missing) > 0 {
|
|
agg.Val.Miss = missing[len(missing)-1]
|
|
}
|
|
return agg
|
|
}
|
|
|
|
// Weight sets the weight field and optionally a value to use when records are
|
|
// missing a value for the field.
|
|
func (agg *WeightedAvgAgg) Weight(field string, missing ...interface{}) *WeightedAvgAgg {
|
|
agg.Weig = new(BaseAggParams)
|
|
agg.Weig.Field = field
|
|
if len(missing) > 0 {
|
|
agg.Weig.Miss = missing[len(missing)-1]
|
|
}
|
|
return agg
|
|
}
|
|
|
|
// Map returns a map representation of the aggregation, thus implementing the
|
|
// Mappable interface.
|
|
func (agg *WeightedAvgAgg) Map() map[string]interface{} {
|
|
return map[string]interface{}{
|
|
agg.apiName: structs.Map(agg),
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------//
|
|
|
|
// CardinalityAgg represents an aggregation of type "cardinality", as described
|
|
// in https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics-cardinality-aggregation.html
|
|
type CardinalityAgg struct {
|
|
*BaseAgg `structs:",flatten"`
|
|
|
|
// PrecisionThr is the precision threshold of the aggregation
|
|
PrecisionThr uint16 `structs:"precision_threshold,omitempty"`
|
|
}
|
|
|
|
// Cardinality creates a new aggregation of type "cardinality" with the provided
|
|
// name and on the provided field.
|
|
func Cardinality(name, field string) *CardinalityAgg {
|
|
return &CardinalityAgg{
|
|
BaseAgg: newBaseAgg("cardinality", name, field),
|
|
}
|
|
}
|
|
|
|
// Missing sets the value to provide for records that are missing a value for
|
|
// the field.
|
|
func (agg *CardinalityAgg) Missing(val interface{}) *CardinalityAgg {
|
|
agg.Miss = val
|
|
return agg
|
|
}
|
|
|
|
// PrecisionThreshold sets the precision threshold of the aggregation.
|
|
func (agg *CardinalityAgg) PrecisionThreshold(val uint16) *CardinalityAgg {
|
|
agg.PrecisionThr = val
|
|
return agg
|
|
}
|
|
|
|
// Map returns a map representation of the aggregation, thus implementing the
|
|
// Mappable interface
|
|
func (agg *CardinalityAgg) Map() map[string]interface{} {
|
|
return map[string]interface{}{
|
|
agg.apiName: structs.Map(agg),
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------//
|
|
|
|
// MaxAgg represents an aggregation of type "max", as described in:
|
|
// https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics-max-aggregation.html
|
|
type MaxAgg struct {
|
|
*BaseAgg `structs:",flatten"`
|
|
}
|
|
|
|
// Max creates a new aggregation of type "max", with the provided name and on
|
|
// the provided field.
|
|
func Max(name, field string) *MaxAgg {
|
|
return &MaxAgg{
|
|
BaseAgg: newBaseAgg("max", name, field),
|
|
}
|
|
}
|
|
|
|
// Missing sets the value to provide for records that are missing a value for
|
|
// the field.
|
|
func (agg *MaxAgg) Missing(val interface{}) *MaxAgg {
|
|
agg.Miss = val
|
|
return agg
|
|
}
|
|
|
|
//----------------------------------------------------------------------------//
|
|
|
|
// MinAgg represents an aggregation of type "min", as described in:
|
|
// https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics-min-aggregation.html
|
|
type MinAgg struct {
|
|
*BaseAgg `structs:",flatten"`
|
|
}
|
|
|
|
// Min creates a new aggregation of type "min", with the provided name and on
|
|
// the provided field.
|
|
func Min(name, field string) *MinAgg {
|
|
return &MinAgg{
|
|
BaseAgg: newBaseAgg("min", name, field),
|
|
}
|
|
}
|
|
|
|
// Missing sets the value to provide for records that are missing a value for
|
|
// the field.
|
|
func (agg *MinAgg) Missing(val interface{}) *MinAgg {
|
|
agg.Miss = val
|
|
return agg
|
|
}
|
|
|
|
//----------------------------------------------------------------------------//
|
|
|
|
// SumAgg represents an aggregation of type "sum", as described in:
|
|
// https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics-sum-aggregation.html
|
|
type SumAgg struct {
|
|
*BaseAgg `structs:",flatten"`
|
|
}
|
|
|
|
// Sum creates a new aggregation of type "sum", with the provided name and on
|
|
// the provided field.
|
|
func Sum(name, field string) *SumAgg {
|
|
return &SumAgg{
|
|
BaseAgg: newBaseAgg("sum", name, field),
|
|
}
|
|
}
|
|
|
|
// Missing sets the value to provide for records that are missing a value for
|
|
// the field.
|
|
func (agg *SumAgg) Missing(val interface{}) *SumAgg {
|
|
agg.Miss = val
|
|
return agg
|
|
}
|
|
|
|
//----------------------------------------------------------------------------//
|
|
|
|
// ValueCountAgg represents an aggregation of type "value_count", as described
|
|
// in https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics-valuecount-aggregation.html
|
|
type ValueCountAgg struct {
|
|
*BaseAgg `structs:",flatten"`
|
|
}
|
|
|
|
// ValueCount creates a new aggregation of type "value_count", with the provided
|
|
// name and on the provided field
|
|
func ValueCount(name, field string) *ValueCountAgg {
|
|
return &ValueCountAgg{
|
|
BaseAgg: newBaseAgg("value_count", name, field),
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------//
|
|
|
|
// PercentilesAgg represents an aggregation of type "percentiles", as described
|
|
// in https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics-percentile-aggregation.html
|
|
type PercentilesAgg struct {
|
|
*BaseAgg `structs:",flatten"`
|
|
|
|
// Prcnts is the aggregation's percentages
|
|
Prcnts []float32 `structs:"percents,omitempty"`
|
|
|
|
// Key denotes whether the aggregation is keyed or not
|
|
Key *bool `structs:"keyed,omitempty"`
|
|
|
|
// TDigest includes options for the TDigest algorithm
|
|
TDigest struct {
|
|
// Compression is the compression level to use
|
|
Compression uint16 `structs:"compression,omitempty"`
|
|
} `structs:"tdigest,omitempty"`
|
|
|
|
// HDR includes options for the HDR implementation
|
|
HDR struct {
|
|
// NumHistogramDigits defines the resolution of values for the histogram
|
|
// in number of significant digits
|
|
NumHistogramDigits uint8 `structs:"number_of_significant_value_digits,omitempty"`
|
|
} `structs:"hdr,omitempty"`
|
|
}
|
|
|
|
// Percentiles creates a new aggregation of type "percentiles" with the provided
|
|
// name and on the provided field.
|
|
func Percentiles(name, field string) *PercentilesAgg {
|
|
return &PercentilesAgg{
|
|
BaseAgg: newBaseAgg("percentiles", name, field),
|
|
}
|
|
}
|
|
|
|
// Percents sets the aggregation's percentages
|
|
func (agg *PercentilesAgg) Percents(percents ...float32) *PercentilesAgg {
|
|
agg.Prcnts = percents
|
|
return agg
|
|
}
|
|
|
|
// Missing sets the value to provide for records that are missing a value for
|
|
// the field.
|
|
func (agg *PercentilesAgg) Missing(val interface{}) *PercentilesAgg {
|
|
agg.Miss = val
|
|
return agg
|
|
}
|
|
|
|
// Keyed sets whether the aggregate is keyed or not.
|
|
func (agg *PercentilesAgg) Keyed(b bool) *PercentilesAgg {
|
|
agg.Key = &b
|
|
return agg
|
|
}
|
|
|
|
// Compression sets the compression level for the aggregation.
|
|
func (agg *PercentilesAgg) Compression(val uint16) *PercentilesAgg {
|
|
agg.TDigest.Compression = val
|
|
return agg
|
|
}
|
|
|
|
// NumHistogramDigits specifies the resolution of values for the histogram in
|
|
// number of significant digits.
|
|
func (agg *PercentilesAgg) NumHistogramDigits(val uint8) *PercentilesAgg {
|
|
agg.HDR.NumHistogramDigits = val
|
|
return agg
|
|
}
|
|
|
|
// Map returns a map representation of the aggregation, thus implementing the
|
|
// Mappable interface.
|
|
func (agg *PercentilesAgg) Map() map[string]interface{} {
|
|
return map[string]interface{}{
|
|
agg.apiName: structs.Map(agg),
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------//
|
|
|
|
// StatsAgg represents an aggregation of type "stats", as described in:
|
|
// https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics-stats-aggregation.html
|
|
type StatsAgg struct {
|
|
*BaseAgg `structs:",flatten"`
|
|
}
|
|
|
|
// Stats creates a new "stats" aggregation with the provided name and on the
|
|
// provided field.
|
|
func Stats(name, field string) *StatsAgg {
|
|
return &StatsAgg{
|
|
BaseAgg: newBaseAgg("stats", name, field),
|
|
}
|
|
}
|
|
|
|
// Missing sets the value to provide for records missing a value for the field.
|
|
func (agg *StatsAgg) Missing(val interface{}) *StatsAgg {
|
|
agg.Miss = val
|
|
return agg
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------//
|
|
|
|
// StringStatsAgg represents an aggregation of type "string_stats", as described
|
|
// in https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics-string-stats-aggregation.html
|
|
type StringStatsAgg struct {
|
|
*BaseAgg `structs:",flatten"`
|
|
|
|
// ShowDist indicates whether to ask ElasticSearch to return a probability
|
|
// distribution for all characters
|
|
ShowDist *bool `structs:"show_distribution,omitempty"`
|
|
}
|
|
|
|
// StringStats creates a new "string_stats" aggregation with the provided name
|
|
// and on the provided field.
|
|
func StringStats(name, field string) *StringStatsAgg {
|
|
return &StringStatsAgg{
|
|
BaseAgg: newBaseAgg("string_stats", name, field),
|
|
}
|
|
}
|
|
|
|
// Missing sets the value to provide for records missing a value for the field.
|
|
func (agg *StringStatsAgg) Missing(val interface{}) *StringStatsAgg {
|
|
agg.Miss = val
|
|
return agg
|
|
}
|
|
|
|
// ShowDistribution sets whether to show the probability distribution for all
|
|
// characters
|
|
func (agg *StringStatsAgg) ShowDistribution(b bool) *StringStatsAgg {
|
|
agg.ShowDist = &b
|
|
return agg
|
|
}
|
|
|
|
// Map returns a map representation of the aggregation, thus implementing the
|
|
// Mappable interface.
|
|
func (agg *StringStatsAgg) Map() map[string]interface{} {
|
|
return map[string]interface{}{
|
|
agg.apiName: structs.Map(agg),
|
|
}
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------//
|
|
|
|
// TopHitsAgg represents an aggregation of type "top_hits", as described
|
|
// in https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics-top-hits-aggregation.html
|
|
type TopHitsAgg struct {
|
|
name string
|
|
from uint64
|
|
size uint64
|
|
sort []map[string]interface{}
|
|
source Source
|
|
}
|
|
|
|
// TopHits creates an aggregation of type "top_hits".
|
|
func TopHits(name string) *TopHitsAgg {
|
|
return &TopHitsAgg{
|
|
name: name,
|
|
}
|
|
}
|
|
|
|
// Name returns the name of the aggregation.
|
|
func (agg *TopHitsAgg) Name() string {
|
|
return agg.name
|
|
}
|
|
|
|
// From sets an offset from the first result to return.
|
|
func (agg *TopHitsAgg) From(offset uint64) *TopHitsAgg {
|
|
agg.from = offset
|
|
return agg
|
|
}
|
|
|
|
// Size sets the maximum number of top matching hits to return per bucket (the
|
|
// default is 3).
|
|
func (agg *TopHitsAgg) Size(size uint64) *TopHitsAgg {
|
|
agg.size = size
|
|
return agg
|
|
}
|
|
|
|
// Sort sets how the top matching hits should be sorted. By default the hits are
|
|
// sorted by the score of the main query.
|
|
func (agg *TopHitsAgg) Sort(name string, order Order) *TopHitsAgg {
|
|
agg.sort = append(agg.sort, map[string]interface{}{
|
|
name: map[string]interface{}{
|
|
"order": order,
|
|
},
|
|
})
|
|
|
|
return agg
|
|
}
|
|
|
|
// SourceIncludes sets the keys to return from the top matching documents.
|
|
func (agg *TopHitsAgg) SourceIncludes(keys ...string) *TopHitsAgg {
|
|
agg.source.includes = keys
|
|
return agg
|
|
}
|
|
|
|
// Map returns a map representation of the aggregation, thus implementing the
|
|
// Mappable interface.
|
|
func (agg *TopHitsAgg) Map() map[string]interface{} {
|
|
innerMap := make(map[string]interface{})
|
|
|
|
if agg.from > 0 {
|
|
innerMap["from"] = agg.from
|
|
}
|
|
if agg.size > 0 {
|
|
innerMap["size"] = agg.size
|
|
}
|
|
if len(agg.sort) > 0 {
|
|
innerMap["sort"] = agg.sort
|
|
}
|
|
if len(agg.source.includes) > 0 {
|
|
innerMap["_source"] = agg.source.Map()
|
|
}
|
|
|
|
return map[string]interface{}{
|
|
"top_hits": innerMap,
|
|
}
|
|
}
|