Skip to content

Commit

Permalink
Merge pull request #6 from GokselKUCUKSAHIN/feature/aggs
Browse files Browse the repository at this point in the history
Feature/aggs
  • Loading branch information
GokselKUCUKSAHIN committed Apr 14, 2024
2 parents 5abaf55 + 9663212 commit c1cb566
Show file tree
Hide file tree
Showing 5 changed files with 526 additions and 5 deletions.
16 changes: 13 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ go get github.com/GokselKUCUKSAHIN/es-query-builder
- [x] add examples
- [ ] add benchmark results
- [x] add `go get` command
- [x] setup github workflow
- [x] add badges
- [x] setup github workflow
- [x] add benchmark
- [x] add missing tests
- [x] add makefile
Expand All @@ -22,14 +23,23 @@ go get github.com/GokselKUCUKSAHIN/es-query-builder
- [x] range
- [x] sort
- [x] nested
- [ ] aggs
- [x] aggs
- [x] terms
- [x] multi_terms
- [x] nested
- [ ] min (later TBD)
- [ ] max (later TBD)
- [ ] avg (later TBD)
- [ ] sum (later TBD)
- [ ] range (later TBD)
- [ ] filter (later TBD)
- [ ] filters (later TBD)
- [x] match
- [x] match_all
- [x] match_none
- [x] minimum_should_match
- [x] boost


### Examples

# 🚧 Still under construction 🚧
Expand Down
135 changes: 135 additions & 0 deletions benchmarks/benchmark_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -613,3 +613,138 @@ func Benchmark_Nested_Example_PureGo(b *testing.B) {
createNestedQueryPureGo()
}
}

//// Aggs Example ////

func createAggsQuery() string {
query := es.NewQuery(
es.Bool().
Must(
es.Term("type", "File"),
).
MustNot(
es.Exists("file.name"),
),
)

query.
Size(5_000).
Sort(
es.Sort("modifiedDate", order.Desc),
es.Sort("indexedAt", order.Desc),
)

query.
Range("indexedAt").
GreaterThan("2020-06-01").
LesserThanOrEqual("now")

query.Aggs("DocumentIds",
es.AggTerms().
Field("document.id").
Size(250).
Aggs("OrderCounts",
es.AggMultiTerms().
Terms(
es.AggTerm("document.orders.count"),
es.AggTerm("files.order.count").
Missing("book.meta.author"),
),
),
)

marshal, err := json.Marshal(query)
if err != nil {
return ""
}
return string(marshal)
}

func createAggsQueryPureGo() string {
query := map[string]interface{}{
"size": 5000,
"sort": []map[string]interface{}{
{
"modifiedDate": map[string]interface{}{
"order": "desc",
},
},
{
"indexedAt": map[string]interface{}{
"order": "desc",
},
},
},
"query": map[string]interface{}{
"range": map[string]interface{}{
"indexedAt": map[string]interface{}{
"gt": "2020-06-01",
"lte": "now",
},
},
"bool": map[string]interface{}{
"must": []map[string]interface{}{
{
"term": map[string]interface{}{
"type": "File",
},
},
},
"must_not": []map[string]interface{}{
{
"exists": map[string]interface{}{
"field": "file.name",
},
},
},
},
},
"aggs": map[string]interface{}{
"DocumentIds": map[string]interface{}{
"terms": map[string]interface{}{
"field": "document.id",
"size": 250,
},
"aggs": map[string]interface{}{
"OrderCounts": map[string]interface{}{
"multi_terms": map[string]interface{}{
"terms": []map[string]interface{}{
{
"field": "document.orders.count",
},
{
"field": "files.order.count",
"missing": "book.meta.author",
},
},
},
},
},
},
},
}

marshal, err := json.Marshal(query)
if err != nil {
return ""
}
return string(marshal)
}

func Test_Aggs_Queries_are_equal(t *testing.T) {
build := createAggsQuery()
pure := createAggsQueryPureGo()
assert.Equal(t, pure, build)
}

func Benchmark_Aggs_Example_Builder(b *testing.B) {
for i := 0; i <= b.N; i++ {
createAggsQuery()
}
}

func Benchmark_Aggs_Example_PureGo(b *testing.B) {
for i := 0; i <= b.N; i++ {
createAggsQueryPureGo()
}
}
85 changes: 85 additions & 0 deletions es/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ type excludesType Array

type nestedType Object

type aggsType Object

type aggTermType Object

func unsafeIsNil(x any) bool {
return (*[2]uintptr)(unsafe.Pointer(&x))[1] == 0
}
Expand Down Expand Up @@ -449,3 +453,84 @@ func (n nestedType) InnerHits(innerHits Object) nestedType {
func (n nestedType) ScoreMode(scoreMode ScoreMode.ScoreMode) nestedType {
return n.putInNested("score_mode", scoreMode)
}

func AggTerm(field string) aggTermType {
return aggTermType{
"field": field,
}
}

func (aggTerm aggTermType) Missing(missing string) aggTermType {
aggTerm["missing"] = missing
return aggTerm
}

func AggTerms() aggsType {
return aggsType{
"terms": Object{},
}
}

func AggMultiTerms() aggsType {
return aggsType{
"multi_terms": Object{},
}
}

func AggCustom(agg Object) aggsType {
return aggsType(agg)
}

func (agg aggsType) putInTheField(key string, value any) aggsType {
for field := range agg {
if fieldObject, ok := agg[field].(Object); ok {
fieldObject[key] = value
}
}
return agg
}

func (agg aggsType) Aggs(name string, nestedAgg aggsType) aggsType {
agg["aggs"] = Object{
name: nestedAgg,
}
return agg
}

func (agg aggsType) Field(field string) aggsType {
return agg.putInTheField("field", field)
}

func (agg aggsType) Size(size int) aggsType {
return agg.putInTheField("size", size)
}

func (agg aggsType) Order(field string, order Order.Order) aggsType {
return agg.putInTheField("order",
Object{
field: order,
},
)
}

func (agg aggsType) Include(include string) aggsType {
return agg.putInTheField("include", include)
}

func (agg aggsType) Exclude(exclude string) aggsType {
return agg.putInTheField("exclude", exclude)
}

func (agg aggsType) Terms(terms ...aggTermType) aggsType {
return agg.putInTheField("terms", terms)
}

func (o Object) Aggs(name string, agg aggsType) Object {
aggs, exists := o["aggs"]
if !exists {
aggs = Object{}
}
aggs.(Object)[name] = agg
o["aggs"] = aggs
return o
}
Loading

0 comments on commit c1cb566

Please sign in to comment.