Merge 9cdcdc171a2b8b66c516dc3ed85f7ac20ec4bb57 into 49a92fc25e9dab2ffe10380889ca01b8b21cb557

This commit is contained in:
Hardy 2021-08-03 11:11:04 +00:00 committed by GitHub
commit 8bf383d306
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 85 additions and 2 deletions

40
query_joining.go Normal file
View File

@ -0,0 +1,40 @@
package esquery
// NestedQuery represents a query of type nested as described in:
// https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-nested-query.html
type NestedQuery struct {
path string
query Mappable
scoreMode string
ignoreUnmapped bool
}
func Nested(path string, query Mappable) *NestedQuery {
return &NestedQuery{
path: path,
query: query,
}
}
func (n *NestedQuery) ScoreMode(mode string) *NestedQuery {
n.scoreMode = mode
return n
}
func (n *NestedQuery) IgnoreUnmapped(val bool) *NestedQuery {
n.ignoreUnmapped = val
return n
}
// Map returns a map representation of the query, thus implementing the
// Mappable interface.
func (n *NestedQuery) Map() map[string]interface{} {
innerMap := map[string]interface{}{"path": n.path, "query": n.query.Map()}
if n.scoreMode != "" {
innerMap["score_mode"] = n.scoreMode
}
if n.ignoreUnmapped == true {
innerMap["ignore_unmapped"] = n.ignoreUnmapped
}
return map[string]interface{}{"nested": innerMap}
}

22
query_joining_test.go Normal file
View File

@ -0,0 +1,22 @@
package esquery
import (
"testing"
)
func TestNested(t *testing.T) {
runMapTests(t, []mapTest{
{
"Nested Query",
Nested("dns_values", Term("dns_values.type", "A")).ScoreMode("max").IgnoreUnmapped(true),
map[string]interface{}{
"nested": map[string]interface{}{
"path": "dns_values",
"query": Term("dns_values.type", "A").Map(),
"score_mode": "max",
"ignore_unmapped": true,
},
},
},
})
}

View File

@ -26,6 +26,7 @@ type SearchRequest struct {
sort Sort sort Sort
source Source source Source
timeout *time.Duration timeout *time.Duration
collapse map[string]interface{}
} }
@ -76,6 +77,15 @@ func (req *SearchRequest) Sort(name string, order Order) *SearchRequest {
return req return req
} }
// Collapse the results
func (req *SearchRequest) Collapse(field string) *SearchRequest {
req.collapse = map[string]interface{}{
"field": field,
}
return req
}
// SearchAfter retrieve the sorted result // SearchAfter retrieve the sorted result
func (req *SearchRequest) SearchAfter(s ...interface{}) *SearchRequest { func (req *SearchRequest) SearchAfter(s ...interface{}) *SearchRequest {
req.searchAfter = append(req.searchAfter, s...) req.searchAfter = append(req.searchAfter, s...)
@ -113,8 +123,6 @@ func (req *SearchRequest) Highlight(highlight Mappable) *SearchRequest {
return req return req
} }
// Map implements the Mappable interface. It converts the request to into a // Map implements the Mappable interface. It converts the request to into a
// nested map[string]interface{}, as expected by the go-elasticsearch library. // nested map[string]interface{}, as expected by the go-elasticsearch library.
func (req *SearchRequest) Map() map[string]interface{} { func (req *SearchRequest) Map() map[string]interface{} {
@ -155,6 +163,9 @@ func (req *SearchRequest) Map() map[string]interface{} {
m["search_after"] = req.searchAfter m["search_after"] = req.searchAfter
} }
if req.collapse != nil {
m["collapse"] = req.collapse
}
source := req.source.Map() source := req.source.Map()
if len(source) > 0 { if len(source) > 0 {

View File

@ -14,6 +14,16 @@ func TestSearchMaps(t *testing.T) {
"search_after": []string{"_id", "name"}, "search_after": []string{"_id", "name"},
}, },
}, },
{
"a simple query with collapse",
Search().Query(Term("user.id", "Tony")).Collapse("user.id"),
map[string]interface{}{
"query": Term("user.id", "Tony").Map(),
"collapse": map[string]interface{}{
"field": "user.id",
},
},
},
{ {
"a simple match_all query with a size and no aggs", "a simple match_all query with a size and no aggs",
Search().Query(MatchAll()).Size(20), Search().Query(MatchAll()).Size(20),