Support _source, sort and post_filter in search requests (#10)
* Add support for post filter in Search
Search requests can now accept a post filter applied after all hits were
returned from the database. For example:
esquery.Search().
Query(...).
Aggs(...).
PostFilter(esquery.Range(field).Gt(0)).
Run(...)
* Add support for _source and sort in search requests
This commit adds the ability to use the "sort" and "_source" attributes
in search requests, via the new methods Sort, SourceIncludes and
SourceExcludes.
This commit is contained in:
@@ -15,12 +15,15 @@ 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 {
|
||||
query Mappable
|
||||
aggs []Aggregation
|
||||
from *uint64
|
||||
size *uint64
|
||||
explain *bool
|
||||
timeout *time.Duration
|
||||
query Mappable
|
||||
aggs []Aggregation
|
||||
postFilter Mappable
|
||||
from *uint64
|
||||
size *uint64
|
||||
explain *bool
|
||||
timeout *time.Duration
|
||||
source Source
|
||||
sort Sort
|
||||
}
|
||||
|
||||
// Search creates a new SearchRequest object, to be filled via method chaining.
|
||||
@@ -36,7 +39,13 @@ func (req *SearchRequest) Query(q Mappable) *SearchRequest {
|
||||
|
||||
// Aggs sets one or more aggregations for the request.
|
||||
func (req *SearchRequest) Aggs(aggs ...Aggregation) *SearchRequest {
|
||||
req.aggs = aggs
|
||||
req.aggs = append(req.aggs, aggs...)
|
||||
return req
|
||||
}
|
||||
|
||||
// PostFilter sets a post_filter for the request.
|
||||
func (req *SearchRequest) PostFilter(filter Mappable) *SearchRequest {
|
||||
req.postFilter = filter
|
||||
return req
|
||||
}
|
||||
|
||||
@@ -53,6 +62,17 @@ func (req *SearchRequest) Size(size uint64) *SearchRequest {
|
||||
return req
|
||||
}
|
||||
|
||||
// Sort sets how the results should be sorted.
|
||||
func (req *SearchRequest) Sort(name string, order Order) *SearchRequest {
|
||||
req.sort = append(req.sort, map[string]interface{}{
|
||||
name: map[string]interface{}{
|
||||
"order": order,
|
||||
},
|
||||
})
|
||||
|
||||
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 {
|
||||
@@ -66,6 +86,18 @@ func (req *SearchRequest) Timeout(dur time.Duration) *SearchRequest {
|
||||
return req
|
||||
}
|
||||
|
||||
// SourceIncludes sets the keys to return from the matching documents.
|
||||
func (req *SearchRequest) SourceIncludes(keys ...string) *SearchRequest {
|
||||
req.source.includes = keys
|
||||
return req
|
||||
}
|
||||
|
||||
// SourceExcludes sets the keys to not return from the matching documents.
|
||||
func (req *SearchRequest) SourceExcludes(keys ...string) *SearchRequest {
|
||||
req.source.excludes = keys
|
||||
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{} {
|
||||
@@ -81,9 +113,15 @@ func (req *SearchRequest) Map() map[string]interface{} {
|
||||
|
||||
m["aggs"] = aggs
|
||||
}
|
||||
if req.postFilter != nil {
|
||||
m["post_filter"] = req.postFilter.Map()
|
||||
}
|
||||
if req.size != nil {
|
||||
m["size"] = *req.size
|
||||
}
|
||||
if len(req.sort) > 0 {
|
||||
m["sort"] = req.sort
|
||||
}
|
||||
if req.from != nil {
|
||||
m["from"] = *req.from
|
||||
}
|
||||
@@ -94,6 +132,11 @@ func (req *SearchRequest) Map() map[string]interface{} {
|
||||
m["timeout"] = fmt.Sprintf("%.0fs", req.timeout.Seconds())
|
||||
}
|
||||
|
||||
source := req.source.Map()
|
||||
if len(source) > 0 {
|
||||
m["_source"] = source
|
||||
}
|
||||
|
||||
return m
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user