Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions query_joining.go
Original file line number Diff line number Diff line change
@@ -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 changes: 22 additions & 0 deletions query_joining_test.go
Original file line number Diff line number Diff line change
@@ -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,
},
},
},
})
}
15 changes: 13 additions & 2 deletions search.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ type SearchRequest struct {
sort Sort
source Source
timeout *time.Duration
collapse map[string]interface{}

}

Expand Down Expand Up @@ -76,6 +77,15 @@ func (req *SearchRequest) Sort(name string, order Order) *SearchRequest {
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
func (req *SearchRequest) SearchAfter(s ...interface{}) *SearchRequest {
req.searchAfter = append(req.searchAfter, s...)
Expand Down Expand Up @@ -113,8 +123,6 @@ func (req *SearchRequest) Highlight(highlight Mappable) *SearchRequest {
return req
}



// 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 @@ -155,6 +163,9 @@ func (req *SearchRequest) Map() map[string]interface{} {
m["search_after"] = req.searchAfter
}

if req.collapse != nil {
m["collapse"] = req.collapse
}

source := req.source.Map()
if len(source) > 0 {
Expand Down
10 changes: 10 additions & 0 deletions search_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,16 @@ func TestSearchMaps(t *testing.T) {
"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",
Search().Query(MatchAll()).Size(20),
Expand Down