Skip to content

Commit 49a92fc

Browse files
hardy4yoozcchamplinHardyoranmoshai
authored
Features: SearchAfter、Term Aggregation Order、Aggregation Include Filter 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 <caleb.champlin@gmail.com> Co-authored-by: Hardy <caoxiaozhen@secnium.com> Co-authored-by: Oran Moshai <12291998+oranmoshai@users.noreply.github.com>
1 parent fc16427 commit 49a92fc

File tree

6 files changed

+127
-20
lines changed

6 files changed

+127
-20
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
.idea/

aggregations_test.go

Lines changed: 70 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,8 @@ func TestAggregations(t *testing.T) {
6161
{
6262
"a complex, multi-aggregation, nested",
6363
Aggregate(
64-
NestedAgg("categories","categories").
65-
Aggs(TermsAgg("type","outdoors")),
64+
NestedAgg("categories", "categories").
65+
Aggs(TermsAgg("type", "outdoors")),
6666
FilterAgg("filtered",
6767
Term("type", "t-shirt")),
6868
),
@@ -72,9 +72,9 @@ func TestAggregations(t *testing.T) {
7272
"nested": map[string]interface{}{
7373
"path": "categories",
7474
},
75-
"aggs": map[string]interface{} {
76-
"type": map[string]interface{} {
77-
"terms": map[string]interface{} {
75+
"aggs": map[string]interface{}{
76+
"type": map[string]interface{}{
77+
"terms": map[string]interface{}{
7878
"field": "outdoors",
7979
},
8080
},
@@ -83,7 +83,7 @@ func TestAggregations(t *testing.T) {
8383
"filtered": map[string]interface{}{
8484
"filter": map[string]interface{}{
8585
"term": map[string]interface{}{
86-
"type": map[string]interface{} {
86+
"type": map[string]interface{}{
8787
"value": "t-shirt",
8888
},
8989
},
@@ -92,5 +92,69 @@ func TestAggregations(t *testing.T) {
9292
},
9393
},
9494
},
95+
{
96+
"order for termsAggs",
97+
//eq.Aggregate(eq.TermsAgg("a1", "FIELD1").Size(0).Aggs(eq.Sum("a2", "FIELD2.SUBFIELD")))
98+
Aggregate(
99+
TermsAgg("categories", "categories").
100+
Order(map[string]string{"priceSum": "desc"}).
101+
Size(5).Aggs(Sum("priceSum", "price"))),
102+
map[string]interface{}{
103+
"aggs": map[string]interface{}{
104+
"categories": map[string]interface{}{
105+
"terms": map[string]interface{}{
106+
"field": "categories",
107+
"order": map[string]interface{}{
108+
"priceSum": "desc",
109+
},
110+
"size": 5,
111+
},
112+
"aggs": map[string]interface{}{
113+
"priceSum": map[string]interface{}{
114+
"sum": map[string]interface{}{
115+
"field": "price",
116+
},
117+
},
118+
},
119+
},
120+
},
121+
},
122+
},
123+
{
124+
"Single include for termsAggs",
125+
//eq.Aggregate(eq.TermsAgg("a1", "FIELD1").Size(0).Aggs(eq.Sum("a2", "FIELD2.SUBFIELD")))
126+
Aggregate(
127+
TermsAgg("categories", "categories").
128+
Include("red.*|blue.*"),
129+
),
130+
map[string]interface{}{
131+
"aggs": map[string]interface{}{
132+
"categories": map[string]interface{}{
133+
"terms": map[string]interface{}{
134+
"field": "categories",
135+
"include": "red.*|blue.*",
136+
},
137+
},
138+
},
139+
},
140+
},
141+
{
142+
"Multi include for termsAggs",
143+
//eq.Aggregate(eq.TermsAgg("a1", "FIELD1").Size(0).Aggs(eq.Sum("a2", "FIELD2.SUBFIELD")))
144+
Aggregate(
145+
TermsAgg("categories", "categories").
146+
Include("red", "blue"),
147+
),
148+
map[string]interface{}{
149+
"aggs": map[string]interface{}{
150+
"categories": map[string]interface{}{
151+
"terms": map[string]interface{}{
152+
"field": "categories",
153+
"include": []string{"red", "blue"},
154+
},
155+
},
156+
},
157+
},
158+
},
95159
})
96160
}

aggs_bucket.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ type TermsAggregation struct {
1212
shardSize *float64
1313
showTermDoc *bool
1414
aggs []Aggregation
15+
order map[string]string
16+
include []string
1517
}
1618

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

59+
// Order sets the sort for terms agg
60+
func (agg *TermsAggregation) Order(order map[string]string) *TermsAggregation {
61+
agg.order = order
62+
return agg
63+
}
64+
65+
// Include filter the values for buckets
66+
func (agg *TermsAggregation) Include(include ...string) *TermsAggregation {
67+
agg.include = include
68+
return agg
69+
}
70+
5771
// Map returns a map representation of the aggregation, thus implementing the
5872
// Mappable interface.
5973
func (agg *TermsAggregation) Map() map[string]interface{} {
@@ -70,6 +84,18 @@ func (agg *TermsAggregation) Map() map[string]interface{} {
7084
if agg.showTermDoc != nil {
7185
innerMap["show_term_doc_count_error"] = *agg.showTermDoc
7286
}
87+
if agg.order != nil {
88+
innerMap["order"] = agg.order
89+
}
90+
91+
if agg.include != nil {
92+
if len(agg.include) <= 1 {
93+
innerMap["include"] = agg.include[0]
94+
} else {
95+
innerMap["include"] = agg.include
96+
}
97+
98+
}
7399

74100
outerMap := map[string]interface{}{
75101
"terms": innerMap,

go.sum

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,5 @@
1-
github.com/elastic/go-elasticsearch v0.0.0 h1:Pd5fqOuBxKxv83b0+xOAJDAkziWYwFinWnBO0y+TZaA=
2-
github.com/elastic/go-elasticsearch v0.0.0/go.mod h1:TkBSJBuTyFdBnrNqoPc54FN0vKf5c04IdM4zuStJ7xg=
31
github.com/elastic/go-elasticsearch/v7 v7.6.0 h1:sYpGLpEFHgLUKLsZUBfuaVI9QgHjS3JdH9fX4/z8QI8=
42
github.com/elastic/go-elasticsearch/v7 v7.6.0/go.mod h1:OJ4wdbtDNk5g503kvlHLyErCgQwwzmDtaFC4XyOxXA4=
5-
github.com/elastic/go-elasticsearch/v8 v8.0.0-20200210103600-aff00e5adfde h1:Y9SZx8RQqFycLxi5W5eFmxMqnmijULVc3LMjBTtZQdM=
6-
github.com/elastic/go-elasticsearch/v8 v8.0.0-20200210103600-aff00e5adfde/go.mod h1:xe9a/L2aeOgFKKgrO3ibQTnMdpAeL0GC+5/HpGScSa4=
73
github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo=
84
github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
95
github.com/jgroeneveld/schema v1.0.0 h1:J0E10CrOkiSEsw6dfb1IfrDJD14pf6QLVJ3tRPl/syI=

search.go

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,18 @@ import (
1515
// Not all features of the search API are currently supported, but a request can
1616
// currently include a query, aggregations, and more.
1717
type SearchRequest struct {
18-
aggs []Aggregation
19-
explain *bool
20-
from *uint64
21-
highlight Mappable
22-
postFilter Mappable
23-
query Mappable
24-
size *uint64
25-
sort Sort
26-
source Source
27-
timeout *time.Duration
18+
aggs []Aggregation
19+
explain *bool
20+
from *uint64
21+
highlight Mappable
22+
searchAfter []interface{}
23+
postFilter Mappable
24+
query Mappable
25+
size *uint64
26+
sort Sort
27+
source Source
28+
timeout *time.Duration
29+
2830
}
2931

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

79+
// SearchAfter retrieve the sorted result
80+
func (req *SearchRequest) SearchAfter(s ...interface{}) *SearchRequest {
81+
req.searchAfter = append(req.searchAfter, s...)
82+
return req
83+
}
84+
7785
// Explain sets whether the ElasticSearch API should return an explanation for
7886
// how each hit's score was calculated.
7987
func (req *SearchRequest) Explain(b bool) *SearchRequest {
@@ -106,6 +114,7 @@ func (req *SearchRequest) Highlight(highlight Mappable) *SearchRequest {
106114
}
107115

108116

117+
109118
// Map implements the Mappable interface. It converts the request to into a
110119
// nested map[string]interface{}, as expected by the go-elasticsearch library.
111120
func (req *SearchRequest) Map() map[string]interface{} {
@@ -142,6 +151,10 @@ func (req *SearchRequest) Map() map[string]interface{} {
142151
if req.highlight != nil {
143152
m["highlight"] = req.highlight.Map()
144153
}
154+
if req.searchAfter != nil {
155+
m["search_after"] = req.searchAfter
156+
}
157+
145158

146159
source := req.source.Map()
147160
if len(source) > 0 {

search_test.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,13 @@ import (
77

88
func TestSearchMaps(t *testing.T) {
99
runMapTests(t, []mapTest{
10+
{
11+
"a simple query with search after",
12+
Search().SearchAfter("_id", "name"),
13+
map[string]interface{}{
14+
"search_after": []string{"_id", "name"},
15+
},
16+
},
1017
{
1118
"a simple match_all query with a size and no aggs",
1219
Search().Query(MatchAll()).Size(20),

0 commit comments

Comments
 (0)