Add support for nested aggregations and filtered aggregations
This commit is contained in:
parent
f7d496389e
commit
39f0dd59c1
|
@ -58,5 +58,39 @@ func TestAggregations(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"a complex, multi-aggregation, nested",
|
||||||
|
Aggregate(
|
||||||
|
NestedAgg("categories","categories").
|
||||||
|
Aggs(TermsAgg("type","outdoors")),
|
||||||
|
FilterAgg("filtered",
|
||||||
|
Term("type", "t-shirt")),
|
||||||
|
),
|
||||||
|
map[string]interface{}{
|
||||||
|
"aggs": map[string]interface{}{
|
||||||
|
"categories": map[string]interface{}{
|
||||||
|
"nested": map[string]interface{}{
|
||||||
|
"path": "categories",
|
||||||
|
},
|
||||||
|
"aggs": map[string]interface{} {
|
||||||
|
"type": map[string]interface{} {
|
||||||
|
"terms": map[string]interface{} {
|
||||||
|
"field": "outdoors",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"filtered": map[string]interface{}{
|
||||||
|
"filter": map[string]interface{}{
|
||||||
|
"term": map[string]interface{}{
|
||||||
|
"type": map[string]interface{} {
|
||||||
|
"value": "t-shirt",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
package esquery
|
||||||
|
|
||||||
|
type FilterAggregation struct {
|
||||||
|
name string
|
||||||
|
filter Mappable
|
||||||
|
aggs []Aggregation
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filter creates a new aggregation of type "filter". The method name includes
|
||||||
|
// the "Agg" suffix to prevent conflict with the "filter" query.
|
||||||
|
func FilterAgg(name string, filter Mappable) *FilterAggregation {
|
||||||
|
return &FilterAggregation{
|
||||||
|
name: name,
|
||||||
|
filter: filter,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Name returns the name of the aggregation.
|
||||||
|
func (agg *FilterAggregation) Name() string {
|
||||||
|
return agg.name
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filter sets the filter items
|
||||||
|
func (agg *FilterAggregation) Filter(filter Mappable) *FilterAggregation {
|
||||||
|
agg.filter = filter
|
||||||
|
return agg
|
||||||
|
}
|
||||||
|
|
||||||
|
// Aggs sets sub-aggregations for the aggregation.
|
||||||
|
func (agg *FilterAggregation) Aggs(aggs ...Aggregation) *FilterAggregation {
|
||||||
|
agg.aggs = aggs
|
||||||
|
return agg
|
||||||
|
}
|
||||||
|
|
||||||
|
func (agg *FilterAggregation) Map() map[string]interface{} {
|
||||||
|
outerMap := map[string]interface{}{
|
||||||
|
"filter": agg.filter.Map(),
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(agg.aggs) > 0 {
|
||||||
|
subAggs := make(map[string]map[string]interface{})
|
||||||
|
for _, sub := range agg.aggs {
|
||||||
|
subAggs[sub.Name()] = sub.Map()
|
||||||
|
}
|
||||||
|
outerMap["aggs"] = subAggs
|
||||||
|
}
|
||||||
|
|
||||||
|
return outerMap
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
package esquery
|
||||||
|
|
||||||
|
import "testing"
|
||||||
|
|
||||||
|
func TestFilterAggs(t *testing.T) {
|
||||||
|
runMapTests(t, []mapTest{
|
||||||
|
{
|
||||||
|
"filter agg: simple",
|
||||||
|
FilterAgg("filtered", Term("type","t-shirt")),
|
||||||
|
map[string]interface{}{
|
||||||
|
"filter": map[string]interface{}{
|
||||||
|
"term": map[string]interface{} {
|
||||||
|
"type": map[string]interface{} {
|
||||||
|
"value": "t-shirt",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filter agg: with aggs",
|
||||||
|
FilterAgg("filtered", Term("type","t-shirt")).
|
||||||
|
Aggs(Avg("avg_price","price")),
|
||||||
|
map[string]interface{}{
|
||||||
|
"filter": map[string]interface{}{
|
||||||
|
"term": map[string]interface{} {
|
||||||
|
"type": map[string]interface{} {
|
||||||
|
"value": "t-shirt",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"aggs": map[string]interface{} {
|
||||||
|
"avg_price": map[string]interface{} {
|
||||||
|
"avg": map[string]interface{}{
|
||||||
|
"field": "price",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
package esquery
|
||||||
|
|
||||||
|
type NestedAggregation struct {
|
||||||
|
name string
|
||||||
|
path string
|
||||||
|
aggs []Aggregation
|
||||||
|
}
|
||||||
|
|
||||||
|
// NestedAgg creates a new aggregation of type "nested". The method name includes
|
||||||
|
// the "Agg" suffix to prevent conflict with the "nested" query.
|
||||||
|
func NestedAgg(name string, path string) *NestedAggregation {
|
||||||
|
return &NestedAggregation{
|
||||||
|
name: name,
|
||||||
|
path: path,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Name returns the name of the aggregation.
|
||||||
|
func (agg *NestedAggregation) Name() string {
|
||||||
|
return agg.name
|
||||||
|
}
|
||||||
|
|
||||||
|
// NumberOfFragments sets the aggregations path
|
||||||
|
func (agg *NestedAggregation) Path(p string) *NestedAggregation {
|
||||||
|
agg.path = p
|
||||||
|
return agg
|
||||||
|
}
|
||||||
|
|
||||||
|
// Aggs sets sub-aggregations for the aggregation.
|
||||||
|
func (agg *NestedAggregation) Aggs(aggs ...Aggregation) *NestedAggregation {
|
||||||
|
agg.aggs = aggs
|
||||||
|
return agg
|
||||||
|
}
|
||||||
|
|
||||||
|
func (agg *NestedAggregation) Map() map[string]interface{} {
|
||||||
|
innerMap := map[string]interface{}{
|
||||||
|
"path": agg.path,
|
||||||
|
}
|
||||||
|
|
||||||
|
outerMap := map[string]interface{}{
|
||||||
|
"nested": innerMap,
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(agg.aggs) > 0 {
|
||||||
|
subAggs := make(map[string]map[string]interface{})
|
||||||
|
for _, sub := range agg.aggs {
|
||||||
|
subAggs[sub.Name()] = sub.Map()
|
||||||
|
}
|
||||||
|
outerMap["aggs"] = subAggs
|
||||||
|
}
|
||||||
|
|
||||||
|
return outerMap
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
package esquery
|
||||||
|
|
||||||
|
import "testing"
|
||||||
|
|
||||||
|
func TestNestedAggs(t *testing.T) {
|
||||||
|
runMapTests(t, []mapTest{
|
||||||
|
{
|
||||||
|
"nested agg: simple",
|
||||||
|
NestedAgg("simple", "categories"),
|
||||||
|
map[string]interface{}{
|
||||||
|
"nested": map[string]interface{}{
|
||||||
|
"path": "categories",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"nested agg: with aggs",
|
||||||
|
NestedAgg("more_nested", "authors").
|
||||||
|
Aggs(TermsAgg("authors","name")),
|
||||||
|
map[string]interface{}{
|
||||||
|
"nested": map[string]interface{}{
|
||||||
|
"path": "authors",
|
||||||
|
},
|
||||||
|
"aggs": map[string]interface{} {
|
||||||
|
"authors": map[string]interface{} {
|
||||||
|
"terms": map[string]interface{} {
|
||||||
|
"field": "name",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
Loading…
Reference in New Issue