Skip to content

Commit

Permalink
Features: SearchAfter、Term Aggregation Order、Aggregation Include Filt…
Browse files Browse the repository at this point in the history
…er Values (#14)

* Add support for multi_match queries

* Add support for highlights

* Add support for nested aggregations and filtered aggregations

* Update README

* Fix formatting

* fix

* feat: add support for search after

* fix:set search after []string to []interface

* fix:add .gitignore

* feat:Support for term aggs order

* Feat: Support include filter for termAggs

* Update aggregations_test.go

Fix conflict.

* Update go.mod

Co-authored-by: Caleb Champlin <[email protected]>
Co-authored-by: Hardy <[email protected]>
Co-authored-by: Oran Moshai <[email protected]>
  • Loading branch information
4 people authored Mar 15, 2021
1 parent fc16427 commit 49a92fc
Show file tree
Hide file tree
Showing 6 changed files with 127 additions and 20 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.idea/
76 changes: 70 additions & 6 deletions aggregations_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@ func TestAggregations(t *testing.T) {
{
"a complex, multi-aggregation, nested",
Aggregate(
NestedAgg("categories","categories").
Aggs(TermsAgg("type","outdoors")),
NestedAgg("categories", "categories").
Aggs(TermsAgg("type", "outdoors")),
FilterAgg("filtered",
Term("type", "t-shirt")),
),
Expand All @@ -72,9 +72,9 @@ func TestAggregations(t *testing.T) {
"nested": map[string]interface{}{
"path": "categories",
},
"aggs": map[string]interface{} {
"type": map[string]interface{} {
"terms": map[string]interface{} {
"aggs": map[string]interface{}{
"type": map[string]interface{}{
"terms": map[string]interface{}{
"field": "outdoors",
},
},
Expand All @@ -83,7 +83,7 @@ func TestAggregations(t *testing.T) {
"filtered": map[string]interface{}{
"filter": map[string]interface{}{
"term": map[string]interface{}{
"type": map[string]interface{} {
"type": map[string]interface{}{
"value": "t-shirt",
},
},
Expand All @@ -92,5 +92,69 @@ func TestAggregations(t *testing.T) {
},
},
},
{
"order for termsAggs",
//eq.Aggregate(eq.TermsAgg("a1", "FIELD1").Size(0).Aggs(eq.Sum("a2", "FIELD2.SUBFIELD")))
Aggregate(
TermsAgg("categories", "categories").
Order(map[string]string{"priceSum": "desc"}).
Size(5).Aggs(Sum("priceSum", "price"))),
map[string]interface{}{
"aggs": map[string]interface{}{
"categories": map[string]interface{}{
"terms": map[string]interface{}{
"field": "categories",
"order": map[string]interface{}{
"priceSum": "desc",
},
"size": 5,
},
"aggs": map[string]interface{}{
"priceSum": map[string]interface{}{
"sum": map[string]interface{}{
"field": "price",
},
},
},
},
},
},
},
{
"Single include for termsAggs",
//eq.Aggregate(eq.TermsAgg("a1", "FIELD1").Size(0).Aggs(eq.Sum("a2", "FIELD2.SUBFIELD")))
Aggregate(
TermsAgg("categories", "categories").
Include("red.*|blue.*"),
),
map[string]interface{}{
"aggs": map[string]interface{}{
"categories": map[string]interface{}{
"terms": map[string]interface{}{
"field": "categories",
"include": "red.*|blue.*",
},
},
},
},
},
{
"Multi include for termsAggs",
//eq.Aggregate(eq.TermsAgg("a1", "FIELD1").Size(0).Aggs(eq.Sum("a2", "FIELD2.SUBFIELD")))
Aggregate(
TermsAgg("categories", "categories").
Include("red", "blue"),
),
map[string]interface{}{
"aggs": map[string]interface{}{
"categories": map[string]interface{}{
"terms": map[string]interface{}{
"field": "categories",
"include": []string{"red", "blue"},
},
},
},
},
},
})
}
26 changes: 26 additions & 0 deletions aggs_bucket.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ type TermsAggregation struct {
shardSize *float64
showTermDoc *bool
aggs []Aggregation
order map[string]string
include []string
}

// TermsAgg creates a new aggregation of type "terms". The method name includes
Expand Down Expand Up @@ -54,6 +56,18 @@ func (agg *TermsAggregation) Aggs(aggs ...Aggregation) *TermsAggregation {
return agg
}

// Order sets the sort for terms agg
func (agg *TermsAggregation) Order(order map[string]string) *TermsAggregation {
agg.order = order
return agg
}

// Include filter the values for buckets
func (agg *TermsAggregation) Include(include ...string) *TermsAggregation {
agg.include = include
return agg
}

// Map returns a map representation of the aggregation, thus implementing the
// Mappable interface.
func (agg *TermsAggregation) Map() map[string]interface{} {
Expand All @@ -70,6 +84,18 @@ func (agg *TermsAggregation) Map() map[string]interface{} {
if agg.showTermDoc != nil {
innerMap["show_term_doc_count_error"] = *agg.showTermDoc
}
if agg.order != nil {
innerMap["order"] = agg.order
}

if agg.include != nil {
if len(agg.include) <= 1 {
innerMap["include"] = agg.include[0]
} else {
innerMap["include"] = agg.include
}

}

outerMap := map[string]interface{}{
"terms": innerMap,
Expand Down
4 changes: 0 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
github.com/elastic/go-elasticsearch v0.0.0 h1:Pd5fqOuBxKxv83b0+xOAJDAkziWYwFinWnBO0y+TZaA=
github.com/elastic/go-elasticsearch v0.0.0/go.mod h1:TkBSJBuTyFdBnrNqoPc54FN0vKf5c04IdM4zuStJ7xg=
github.com/elastic/go-elasticsearch/v7 v7.6.0 h1:sYpGLpEFHgLUKLsZUBfuaVI9QgHjS3JdH9fX4/z8QI8=
github.com/elastic/go-elasticsearch/v7 v7.6.0/go.mod h1:OJ4wdbtDNk5g503kvlHLyErCgQwwzmDtaFC4XyOxXA4=
github.com/elastic/go-elasticsearch/v8 v8.0.0-20200210103600-aff00e5adfde h1:Y9SZx8RQqFycLxi5W5eFmxMqnmijULVc3LMjBTtZQdM=
github.com/elastic/go-elasticsearch/v8 v8.0.0-20200210103600-aff00e5adfde/go.mod h1:xe9a/L2aeOgFKKgrO3ibQTnMdpAeL0GC+5/HpGScSa4=
github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo=
github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
github.com/jgroeneveld/schema v1.0.0 h1:J0E10CrOkiSEsw6dfb1IfrDJD14pf6QLVJ3tRPl/syI=
Expand Down
33 changes: 23 additions & 10 deletions search.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,18 @@ import (
// Not all features of the search API are currently supported, but a request can
// currently include a query, aggregations, and more.
type SearchRequest struct {
aggs []Aggregation
explain *bool
from *uint64
highlight Mappable
postFilter Mappable
query Mappable
size *uint64
sort Sort
source Source
timeout *time.Duration
aggs []Aggregation
explain *bool
from *uint64
highlight Mappable
searchAfter []interface{}
postFilter Mappable
query Mappable
size *uint64
sort Sort
source Source
timeout *time.Duration

}

// Search creates a new SearchRequest object, to be filled via method chaining.
Expand Down Expand Up @@ -74,6 +76,12 @@ func (req *SearchRequest) Sort(name string, order Order) *SearchRequest {
return req
}

// SearchAfter retrieve the sorted result
func (req *SearchRequest) SearchAfter(s ...interface{}) *SearchRequest {
req.searchAfter = append(req.searchAfter, s...)
return req
}

// Explain sets whether the ElasticSearch API should return an explanation for
// how each hit's score was calculated.
func (req *SearchRequest) Explain(b bool) *SearchRequest {
Expand Down Expand Up @@ -106,6 +114,7 @@ func (req *SearchRequest) Highlight(highlight Mappable) *SearchRequest {
}



// Map implements the Mappable interface. It converts the request to into a
// nested map[string]interface{}, as expected by the go-elasticsearch library.
func (req *SearchRequest) Map() map[string]interface{} {
Expand Down Expand Up @@ -142,6 +151,10 @@ func (req *SearchRequest) Map() map[string]interface{} {
if req.highlight != nil {
m["highlight"] = req.highlight.Map()
}
if req.searchAfter != nil {
m["search_after"] = req.searchAfter
}


source := req.source.Map()
if len(source) > 0 {
Expand Down
7 changes: 7 additions & 0 deletions search_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@ import (

func TestSearchMaps(t *testing.T) {
runMapTests(t, []mapTest{
{
"a simple query with search after",
Search().SearchAfter("_id", "name"),
map[string]interface{}{
"search_after": []string{"_id", "name"},
},
},
{
"a simple match_all query with a size and no aggs",
Search().Query(MatchAll()).Size(20),
Expand Down

0 comments on commit 49a92fc

Please sign in to comment.