summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/olivere/elastic/sort.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/olivere/elastic/sort.go')
-rw-r--r--vendor/github.com/olivere/elastic/sort.go614
1 files changed, 614 insertions, 0 deletions
diff --git a/vendor/github.com/olivere/elastic/sort.go b/vendor/github.com/olivere/elastic/sort.go
new file mode 100644
index 000000000..7e2b32183
--- /dev/null
+++ b/vendor/github.com/olivere/elastic/sort.go
@@ -0,0 +1,614 @@
+// Copyright 2012-present Oliver Eilhard. All rights reserved.
+// Use of this source code is governed by a MIT-license.
+// See http://olivere.mit-license.org/license.txt for details.
+
+package elastic
+
+import "errors"
+
+// -- Sorter --
+
+// Sorter is an interface for sorting strategies, e.g. ScoreSort or FieldSort.
+// See https://www.elastic.co/guide/en/elasticsearch/reference/6.0/search-request-sort.html.
+type Sorter interface {
+ Source() (interface{}, error)
+}
+
+// -- SortInfo --
+
+// SortInfo contains information about sorting a field.
+type SortInfo struct {
+ Sorter
+ Field string
+ Ascending bool
+ Missing interface{}
+ IgnoreUnmapped *bool
+ UnmappedType string
+ SortMode string
+ NestedFilter Query
+ NestedPath string
+ NestedSort *NestedSort // available in 6.1 or later
+}
+
+func (info SortInfo) Source() (interface{}, error) {
+ prop := make(map[string]interface{})
+ if info.Ascending {
+ prop["order"] = "asc"
+ } else {
+ prop["order"] = "desc"
+ }
+ if info.Missing != nil {
+ prop["missing"] = info.Missing
+ }
+ if info.IgnoreUnmapped != nil {
+ prop["ignore_unmapped"] = *info.IgnoreUnmapped
+ }
+ if info.UnmappedType != "" {
+ prop["unmapped_type"] = info.UnmappedType
+ }
+ if info.SortMode != "" {
+ prop["mode"] = info.SortMode
+ }
+ if info.NestedFilter != nil {
+ src, err := info.NestedFilter.Source()
+ if err != nil {
+ return nil, err
+ }
+ prop["nested_filter"] = src
+ }
+ if info.NestedPath != "" {
+ prop["nested_path"] = info.NestedPath
+ }
+ if info.NestedSort != nil {
+ src, err := info.NestedSort.Source()
+ if err != nil {
+ return nil, err
+ }
+ prop["nested"] = src
+ }
+ source := make(map[string]interface{})
+ source[info.Field] = prop
+ return source, nil
+}
+
+// -- SortByDoc --
+
+// SortByDoc sorts by the "_doc" field, as described in
+// https://www.elastic.co/guide/en/elasticsearch/reference/6.0/search-request-scroll.html.
+//
+// Example:
+// ss := elastic.NewSearchSource()
+// ss = ss.SortBy(elastic.SortByDoc{})
+type SortByDoc struct {
+ Sorter
+}
+
+// Source returns the JSON-serializable data.
+func (s SortByDoc) Source() (interface{}, error) {
+ return "_doc", nil
+}
+
+// -- ScoreSort --
+
+// ScoreSort sorts by relevancy score.
+type ScoreSort struct {
+ Sorter
+ ascending bool
+}
+
+// NewScoreSort creates a new ScoreSort.
+func NewScoreSort() *ScoreSort {
+ return &ScoreSort{ascending: false} // Descending by default!
+}
+
+// Order defines whether sorting ascending (default) or descending.
+func (s *ScoreSort) Order(ascending bool) *ScoreSort {
+ s.ascending = ascending
+ return s
+}
+
+// Asc sets ascending sort order.
+func (s *ScoreSort) Asc() *ScoreSort {
+ s.ascending = true
+ return s
+}
+
+// Desc sets descending sort order.
+func (s *ScoreSort) Desc() *ScoreSort {
+ s.ascending = false
+ return s
+}
+
+// Source returns the JSON-serializable data.
+func (s *ScoreSort) Source() (interface{}, error) {
+ source := make(map[string]interface{})
+ x := make(map[string]interface{})
+ source["_score"] = x
+ if s.ascending {
+ x["order"] = "asc"
+ } else {
+ x["order"] = "desc"
+ }
+ return source, nil
+}
+
+// -- FieldSort --
+
+// FieldSort sorts by a given field.
+type FieldSort struct {
+ Sorter
+ fieldName string
+ ascending bool
+ missing interface{}
+ unmappedType *string
+ sortMode *string
+ nestedFilter Query
+ nestedPath *string
+ nestedSort *NestedSort
+}
+
+// NewFieldSort creates a new FieldSort.
+func NewFieldSort(fieldName string) *FieldSort {
+ return &FieldSort{
+ fieldName: fieldName,
+ ascending: true,
+ }
+}
+
+// FieldName specifies the name of the field to be used for sorting.
+func (s *FieldSort) FieldName(fieldName string) *FieldSort {
+ s.fieldName = fieldName
+ return s
+}
+
+// Order defines whether sorting ascending (default) or descending.
+func (s *FieldSort) Order(ascending bool) *FieldSort {
+ s.ascending = ascending
+ return s
+}
+
+// Asc sets ascending sort order.
+func (s *FieldSort) Asc() *FieldSort {
+ s.ascending = true
+ return s
+}
+
+// Desc sets descending sort order.
+func (s *FieldSort) Desc() *FieldSort {
+ s.ascending = false
+ return s
+}
+
+// Missing sets the value to be used when a field is missing in a document.
+// You can also use "_last" or "_first" to sort missing last or first
+// respectively.
+func (s *FieldSort) Missing(missing interface{}) *FieldSort {
+ s.missing = missing
+ return s
+}
+
+// UnmappedType sets the type to use when the current field is not mapped
+// in an index.
+func (s *FieldSort) UnmappedType(typ string) *FieldSort {
+ s.unmappedType = &typ
+ return s
+}
+
+// SortMode specifies what values to pick in case a document contains
+// multiple values for the targeted sort field. Possible values are:
+// min, max, sum, and avg.
+func (s *FieldSort) SortMode(sortMode string) *FieldSort {
+ s.sortMode = &sortMode
+ return s
+}
+
+// NestedFilter sets a filter that nested objects should match with
+// in order to be taken into account for sorting.
+func (s *FieldSort) NestedFilter(nestedFilter Query) *FieldSort {
+ s.nestedFilter = nestedFilter
+ return s
+}
+
+// NestedPath is used if sorting occurs on a field that is inside a
+// nested object.
+func (s *FieldSort) NestedPath(nestedPath string) *FieldSort {
+ s.nestedPath = &nestedPath
+ return s
+}
+
+// NestedSort is available starting with 6.1 and will replace NestedFilter
+// and NestedPath.
+func (s *FieldSort) NestedSort(nestedSort *NestedSort) *FieldSort {
+ s.nestedSort = nestedSort
+ return s
+}
+
+// Source returns the JSON-serializable data.
+func (s *FieldSort) Source() (interface{}, error) {
+ source := make(map[string]interface{})
+ x := make(map[string]interface{})
+ source[s.fieldName] = x
+ if s.ascending {
+ x["order"] = "asc"
+ } else {
+ x["order"] = "desc"
+ }
+ if s.missing != nil {
+ x["missing"] = s.missing
+ }
+ if s.unmappedType != nil {
+ x["unmapped_type"] = *s.unmappedType
+ }
+ if s.sortMode != nil {
+ x["mode"] = *s.sortMode
+ }
+ if s.nestedFilter != nil {
+ src, err := s.nestedFilter.Source()
+ if err != nil {
+ return nil, err
+ }
+ x["nested_filter"] = src
+ }
+ if s.nestedPath != nil {
+ x["nested_path"] = *s.nestedPath
+ }
+ if s.nestedSort != nil {
+ src, err := s.nestedSort.Source()
+ if err != nil {
+ return nil, err
+ }
+ x["nested"] = src
+ }
+ return source, nil
+}
+
+// -- GeoDistanceSort --
+
+// GeoDistanceSort allows for sorting by geographic distance.
+// See https://www.elastic.co/guide/en/elasticsearch/reference/6.0/search-request-sort.html#_geo_distance_sorting.
+type GeoDistanceSort struct {
+ Sorter
+ fieldName string
+ points []*GeoPoint
+ geohashes []string
+ distanceType *string
+ unit string
+ ascending bool
+ sortMode *string
+ nestedFilter Query
+ nestedPath *string
+ nestedSort *NestedSort
+}
+
+// NewGeoDistanceSort creates a new sorter for geo distances.
+func NewGeoDistanceSort(fieldName string) *GeoDistanceSort {
+ return &GeoDistanceSort{
+ fieldName: fieldName,
+ ascending: true,
+ }
+}
+
+// FieldName specifies the name of the (geo) field to use for sorting.
+func (s *GeoDistanceSort) FieldName(fieldName string) *GeoDistanceSort {
+ s.fieldName = fieldName
+ return s
+}
+
+// Order defines whether sorting ascending (default) or descending.
+func (s *GeoDistanceSort) Order(ascending bool) *GeoDistanceSort {
+ s.ascending = ascending
+ return s
+}
+
+// Asc sets ascending sort order.
+func (s *GeoDistanceSort) Asc() *GeoDistanceSort {
+ s.ascending = true
+ return s
+}
+
+// Desc sets descending sort order.
+func (s *GeoDistanceSort) Desc() *GeoDistanceSort {
+ s.ascending = false
+ return s
+}
+
+// Point specifies a point to create the range distance aggregations from.
+func (s *GeoDistanceSort) Point(lat, lon float64) *GeoDistanceSort {
+ s.points = append(s.points, GeoPointFromLatLon(lat, lon))
+ return s
+}
+
+// Points specifies the geo point(s) to create the range distance aggregations from.
+func (s *GeoDistanceSort) Points(points ...*GeoPoint) *GeoDistanceSort {
+ s.points = append(s.points, points...)
+ return s
+}
+
+// GeoHashes specifies the geo point to create the range distance aggregations from.
+func (s *GeoDistanceSort) GeoHashes(geohashes ...string) *GeoDistanceSort {
+ s.geohashes = append(s.geohashes, geohashes...)
+ return s
+}
+
+// Unit specifies the distance unit to use. It defaults to km.
+// See https://www.elastic.co/guide/en/elasticsearch/reference/6.0/common-options.html#distance-units
+// for details.
+func (s *GeoDistanceSort) Unit(unit string) *GeoDistanceSort {
+ s.unit = unit
+ return s
+}
+
+// GeoDistance is an alias for DistanceType.
+func (s *GeoDistanceSort) GeoDistance(geoDistance string) *GeoDistanceSort {
+ return s.DistanceType(geoDistance)
+}
+
+// DistanceType describes how to compute the distance, e.g. "arc" or "plane".
+// See https://www.elastic.co/guide/en/elasticsearch/reference/6.0/search-request-sort.html#geo-sorting
+// for details.
+func (s *GeoDistanceSort) DistanceType(distanceType string) *GeoDistanceSort {
+ s.distanceType = &distanceType
+ return s
+}
+
+// SortMode specifies what values to pick in case a document contains
+// multiple values for the targeted sort field. Possible values are:
+// min, max, sum, and avg.
+func (s *GeoDistanceSort) SortMode(sortMode string) *GeoDistanceSort {
+ s.sortMode = &sortMode
+ return s
+}
+
+// NestedFilter sets a filter that nested objects should match with
+// in order to be taken into account for sorting.
+func (s *GeoDistanceSort) NestedFilter(nestedFilter Query) *GeoDistanceSort {
+ s.nestedFilter = nestedFilter
+ return s
+}
+
+// NestedPath is used if sorting occurs on a field that is inside a
+// nested object.
+func (s *GeoDistanceSort) NestedPath(nestedPath string) *GeoDistanceSort {
+ s.nestedPath = &nestedPath
+ return s
+}
+
+// NestedSort is available starting with 6.1 and will replace NestedFilter
+// and NestedPath.
+func (s *GeoDistanceSort) NestedSort(nestedSort *NestedSort) *GeoDistanceSort {
+ s.nestedSort = nestedSort
+ return s
+}
+
+// Source returns the JSON-serializable data.
+func (s *GeoDistanceSort) Source() (interface{}, error) {
+ source := make(map[string]interface{})
+ x := make(map[string]interface{})
+ source["_geo_distance"] = x
+
+ // Points
+ var ptarr []interface{}
+ for _, pt := range s.points {
+ ptarr = append(ptarr, pt.Source())
+ }
+ for _, geohash := range s.geohashes {
+ ptarr = append(ptarr, geohash)
+ }
+ x[s.fieldName] = ptarr
+
+ if s.unit != "" {
+ x["unit"] = s.unit
+ }
+ if s.distanceType != nil {
+ x["distance_type"] = *s.distanceType
+ }
+
+ if s.ascending {
+ x["order"] = "asc"
+ } else {
+ x["order"] = "desc"
+ }
+ if s.sortMode != nil {
+ x["mode"] = *s.sortMode
+ }
+ if s.nestedFilter != nil {
+ src, err := s.nestedFilter.Source()
+ if err != nil {
+ return nil, err
+ }
+ x["nested_filter"] = src
+ }
+ if s.nestedPath != nil {
+ x["nested_path"] = *s.nestedPath
+ }
+ if s.nestedSort != nil {
+ src, err := s.nestedSort.Source()
+ if err != nil {
+ return nil, err
+ }
+ x["nested"] = src
+ }
+ return source, nil
+}
+
+// -- ScriptSort --
+
+// ScriptSort sorts by a custom script. See
+// https://www.elastic.co/guide/en/elasticsearch/reference/6.0/modules-scripting.html#modules-scripting
+// for details about scripting.
+type ScriptSort struct {
+ Sorter
+ script *Script
+ typ string
+ ascending bool
+ sortMode *string
+ nestedFilter Query
+ nestedPath *string
+ nestedSort *NestedSort
+}
+
+// NewScriptSort creates and initializes a new ScriptSort.
+// You must provide a script and a type, e.g. "string" or "number".
+func NewScriptSort(script *Script, typ string) *ScriptSort {
+ return &ScriptSort{
+ script: script,
+ typ: typ,
+ ascending: true,
+ }
+}
+
+// Type sets the script type, which can be either "string" or "number".
+func (s *ScriptSort) Type(typ string) *ScriptSort {
+ s.typ = typ
+ return s
+}
+
+// Order defines whether sorting ascending (default) or descending.
+func (s *ScriptSort) Order(ascending bool) *ScriptSort {
+ s.ascending = ascending
+ return s
+}
+
+// Asc sets ascending sort order.
+func (s *ScriptSort) Asc() *ScriptSort {
+ s.ascending = true
+ return s
+}
+
+// Desc sets descending sort order.
+func (s *ScriptSort) Desc() *ScriptSort {
+ s.ascending = false
+ return s
+}
+
+// SortMode specifies what values to pick in case a document contains
+// multiple values for the targeted sort field. Possible values are:
+// min or max.
+func (s *ScriptSort) SortMode(sortMode string) *ScriptSort {
+ s.sortMode = &sortMode
+ return s
+}
+
+// NestedFilter sets a filter that nested objects should match with
+// in order to be taken into account for sorting.
+func (s *ScriptSort) NestedFilter(nestedFilter Query) *ScriptSort {
+ s.nestedFilter = nestedFilter
+ return s
+}
+
+// NestedPath is used if sorting occurs on a field that is inside a
+// nested object.
+func (s *ScriptSort) NestedPath(nestedPath string) *ScriptSort {
+ s.nestedPath = &nestedPath
+ return s
+}
+
+// NestedSort is available starting with 6.1 and will replace NestedFilter
+// and NestedPath.
+func (s *ScriptSort) NestedSort(nestedSort *NestedSort) *ScriptSort {
+ s.nestedSort = nestedSort
+ return s
+}
+
+// Source returns the JSON-serializable data.
+func (s *ScriptSort) Source() (interface{}, error) {
+ if s.script == nil {
+ return nil, errors.New("ScriptSort expected a script")
+ }
+ source := make(map[string]interface{})
+ x := make(map[string]interface{})
+ source["_script"] = x
+
+ src, err := s.script.Source()
+ if err != nil {
+ return nil, err
+ }
+ x["script"] = src
+
+ x["type"] = s.typ
+
+ if s.ascending {
+ x["order"] = "asc"
+ } else {
+ x["order"] = "desc"
+ }
+ if s.sortMode != nil {
+ x["mode"] = *s.sortMode
+ }
+ if s.nestedFilter != nil {
+ src, err := s.nestedFilter.Source()
+ if err != nil {
+ return nil, err
+ }
+ x["nested_filter"] = src
+ }
+ if s.nestedPath != nil {
+ x["nested_path"] = *s.nestedPath
+ }
+ if s.nestedSort != nil {
+ src, err := s.nestedSort.Source()
+ if err != nil {
+ return nil, err
+ }
+ x["nested"] = src
+ }
+ return source, nil
+}
+
+// -- NestedSort --
+
+// NestedSort is used for fields that are inside a nested object.
+// It takes a "path" argument and an optional nested filter that the
+// nested objects should match with in order to be taken into account
+// for sorting.
+//
+// NestedSort is available from 6.1 and replaces nestedFilter and nestedPath
+// in the other sorters.
+type NestedSort struct {
+ Sorter
+ path string
+ filter Query
+ nestedSort *NestedSort
+}
+
+// NewNestedSort creates a new NestedSort.
+func NewNestedSort(path string) *NestedSort {
+ return &NestedSort{path: path}
+}
+
+// Filter sets the filter.
+func (s *NestedSort) Filter(filter Query) *NestedSort {
+ s.filter = filter
+ return s
+}
+
+// NestedSort embeds another level of nested sorting.
+func (s *NestedSort) NestedSort(nestedSort *NestedSort) *NestedSort {
+ s.nestedSort = nestedSort
+ return s
+}
+
+// Source returns the JSON-serializable data.
+func (s *NestedSort) Source() (interface{}, error) {
+ source := make(map[string]interface{})
+
+ if s.path != "" {
+ source["path"] = s.path
+ }
+ if s.filter != nil {
+ src, err := s.filter.Source()
+ if err != nil {
+ return nil, err
+ }
+ source["filter"] = src
+ }
+ if s.nestedSort != nil {
+ src, err := s.nestedSort.Source()
+ if err != nil {
+ return nil, err
+ }
+ source["nested"] = src
+ }
+
+ return source, nil
+}