search_aggs_range.go 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. // Copyright 2012-2015 Oliver Eilhard. All rights reserved.
  2. // Use of this source code is governed by a MIT-license.
  3. // See http://olivere.mit-license.org/license.txt for details.
  4. package elastic
  5. import (
  6. "time"
  7. )
  8. // RangeAggregation is a multi-bucket value source based aggregation that
  9. // enables the user to define a set of ranges - each representing a bucket.
  10. // During the aggregation process, the values extracted from each document
  11. // will be checked against each bucket range and "bucket" the
  12. // relevant/matching document. Note that this aggregration includes the
  13. // from value and excludes the to value for each range.
  14. // See: http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-aggregations-bucket-range-aggregation.html
  15. type RangeAggregation struct {
  16. field string
  17. script string
  18. scriptFile string
  19. lang string
  20. params map[string]interface{}
  21. subAggregations map[string]Aggregation
  22. keyed *bool
  23. unmapped *bool
  24. entries []rangeAggregationEntry
  25. }
  26. type rangeAggregationEntry struct {
  27. Key string
  28. From interface{}
  29. To interface{}
  30. }
  31. func NewRangeAggregation() RangeAggregation {
  32. a := RangeAggregation{
  33. params: make(map[string]interface{}),
  34. subAggregations: make(map[string]Aggregation),
  35. entries: make([]rangeAggregationEntry, 0),
  36. }
  37. return a
  38. }
  39. func (a RangeAggregation) Field(field string) RangeAggregation {
  40. a.field = field
  41. return a
  42. }
  43. func (a RangeAggregation) Script(script string) RangeAggregation {
  44. a.script = script
  45. return a
  46. }
  47. func (a RangeAggregation) ScriptFile(scriptFile string) RangeAggregation {
  48. a.scriptFile = scriptFile
  49. return a
  50. }
  51. func (a RangeAggregation) Lang(lang string) RangeAggregation {
  52. a.lang = lang
  53. return a
  54. }
  55. func (a RangeAggregation) Param(name string, value interface{}) RangeAggregation {
  56. a.params[name] = value
  57. return a
  58. }
  59. func (a RangeAggregation) SubAggregation(name string, subAggregation Aggregation) RangeAggregation {
  60. a.subAggregations[name] = subAggregation
  61. return a
  62. }
  63. func (a RangeAggregation) Keyed(keyed bool) RangeAggregation {
  64. a.keyed = &keyed
  65. return a
  66. }
  67. func (a RangeAggregation) Unmapped(unmapped bool) RangeAggregation {
  68. a.unmapped = &unmapped
  69. return a
  70. }
  71. func (a RangeAggregation) AddRange(from, to interface{}) RangeAggregation {
  72. a.entries = append(a.entries, rangeAggregationEntry{From: from, To: to})
  73. return a
  74. }
  75. func (a RangeAggregation) AddRangeWithKey(key string, from, to interface{}) RangeAggregation {
  76. a.entries = append(a.entries, rangeAggregationEntry{Key: key, From: from, To: to})
  77. return a
  78. }
  79. func (a RangeAggregation) AddUnboundedTo(from interface{}) RangeAggregation {
  80. a.entries = append(a.entries, rangeAggregationEntry{From: from, To: nil})
  81. return a
  82. }
  83. func (a RangeAggregation) AddUnboundedToWithKey(key string, from interface{}) RangeAggregation {
  84. a.entries = append(a.entries, rangeAggregationEntry{Key: key, From: from, To: nil})
  85. return a
  86. }
  87. func (a RangeAggregation) AddUnboundedFrom(to interface{}) RangeAggregation {
  88. a.entries = append(a.entries, rangeAggregationEntry{From: nil, To: to})
  89. return a
  90. }
  91. func (a RangeAggregation) AddUnboundedFromWithKey(key string, to interface{}) RangeAggregation {
  92. a.entries = append(a.entries, rangeAggregationEntry{Key: key, From: nil, To: to})
  93. return a
  94. }
  95. func (a RangeAggregation) Lt(to interface{}) RangeAggregation {
  96. a.entries = append(a.entries, rangeAggregationEntry{From: nil, To: to})
  97. return a
  98. }
  99. func (a RangeAggregation) LtWithKey(key string, to interface{}) RangeAggregation {
  100. a.entries = append(a.entries, rangeAggregationEntry{Key: key, From: nil, To: to})
  101. return a
  102. }
  103. func (a RangeAggregation) Between(from, to interface{}) RangeAggregation {
  104. a.entries = append(a.entries, rangeAggregationEntry{From: from, To: to})
  105. return a
  106. }
  107. func (a RangeAggregation) BetweenWithKey(key string, from, to interface{}) RangeAggregation {
  108. a.entries = append(a.entries, rangeAggregationEntry{Key: key, From: from, To: to})
  109. return a
  110. }
  111. func (a RangeAggregation) Gt(from interface{}) RangeAggregation {
  112. a.entries = append(a.entries, rangeAggregationEntry{From: from, To: nil})
  113. return a
  114. }
  115. func (a RangeAggregation) GtWithKey(key string, from interface{}) RangeAggregation {
  116. a.entries = append(a.entries, rangeAggregationEntry{Key: key, From: from, To: nil})
  117. return a
  118. }
  119. func (a RangeAggregation) Source() interface{} {
  120. // Example:
  121. // {
  122. // "aggs" : {
  123. // "price_ranges" : {
  124. // "range" : {
  125. // "field" : "price",
  126. // "ranges" : [
  127. // { "to" : 50 },
  128. // { "from" : 50, "to" : 100 },
  129. // { "from" : 100 }
  130. // ]
  131. // }
  132. // }
  133. // }
  134. // }
  135. //
  136. // This method returns only the { "range" : { ... } } part.
  137. source := make(map[string]interface{})
  138. opts := make(map[string]interface{})
  139. source["range"] = opts
  140. // ValuesSourceAggregationBuilder
  141. if a.field != "" {
  142. opts["field"] = a.field
  143. }
  144. if a.script != "" {
  145. opts["script"] = a.script
  146. }
  147. if a.scriptFile != "" {
  148. opts["script_file"] = a.scriptFile
  149. }
  150. if a.lang != "" {
  151. opts["lang"] = a.lang
  152. }
  153. if len(a.params) > 0 {
  154. opts["params"] = a.params
  155. }
  156. if a.keyed != nil {
  157. opts["keyed"] = *a.keyed
  158. }
  159. if a.unmapped != nil {
  160. opts["unmapped"] = *a.unmapped
  161. }
  162. ranges := make([]interface{}, 0)
  163. for _, ent := range a.entries {
  164. r := make(map[string]interface{})
  165. if ent.Key != "" {
  166. r["key"] = ent.Key
  167. }
  168. if ent.From != nil {
  169. switch from := ent.From.(type) {
  170. case int, int16, int32, int64, float32, float64:
  171. r["from"] = from
  172. case time.Time:
  173. r["from"] = from.Format(time.RFC3339)
  174. case string:
  175. r["from"] = from
  176. }
  177. }
  178. if ent.To != nil {
  179. switch to := ent.To.(type) {
  180. case int, int16, int32, int64, float32, float64:
  181. r["to"] = to
  182. case time.Time:
  183. r["to"] = to.Format(time.RFC3339)
  184. case string:
  185. r["to"] = to
  186. }
  187. }
  188. ranges = append(ranges, r)
  189. }
  190. opts["ranges"] = ranges
  191. // AggregationBuilder (SubAggregations)
  192. if len(a.subAggregations) > 0 {
  193. aggsMap := make(map[string]interface{})
  194. source["aggregations"] = aggsMap
  195. for name, aggregate := range a.subAggregations {
  196. aggsMap[name] = aggregate.Source()
  197. }
  198. }
  199. return source
  200. }