search_aggs_bucket_date_histogram.go 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  1. // Copyright 2012-present 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. // DateHistogramAggregation is a multi-bucket aggregation similar to the
  6. // histogram except it can only be applied on date values.
  7. // See: https://www.elastic.co/guide/en/elasticsearch/reference/5.2/search-aggregations-bucket-datehistogram-aggregation.html
  8. type DateHistogramAggregation struct {
  9. field string
  10. script *Script
  11. missing interface{}
  12. subAggregations map[string]Aggregation
  13. meta map[string]interface{}
  14. interval string
  15. order string
  16. orderAsc bool
  17. minDocCount *int64
  18. extendedBoundsMin interface{}
  19. extendedBoundsMax interface{}
  20. timeZone string
  21. format string
  22. offset string
  23. keyed *bool
  24. }
  25. // NewDateHistogramAggregation creates a new DateHistogramAggregation.
  26. func NewDateHistogramAggregation() *DateHistogramAggregation {
  27. return &DateHistogramAggregation{
  28. subAggregations: make(map[string]Aggregation),
  29. }
  30. }
  31. // Field on which the aggregation is processed.
  32. func (a *DateHistogramAggregation) Field(field string) *DateHistogramAggregation {
  33. a.field = field
  34. return a
  35. }
  36. func (a *DateHistogramAggregation) Script(script *Script) *DateHistogramAggregation {
  37. a.script = script
  38. return a
  39. }
  40. // Missing configures the value to use when documents miss a value.
  41. func (a *DateHistogramAggregation) Missing(missing interface{}) *DateHistogramAggregation {
  42. a.missing = missing
  43. return a
  44. }
  45. func (a *DateHistogramAggregation) SubAggregation(name string, subAggregation Aggregation) *DateHistogramAggregation {
  46. a.subAggregations[name] = subAggregation
  47. return a
  48. }
  49. // Meta sets the meta data to be included in the aggregation response.
  50. func (a *DateHistogramAggregation) Meta(metaData map[string]interface{}) *DateHistogramAggregation {
  51. a.meta = metaData
  52. return a
  53. }
  54. // Interval by which the aggregation gets processed.
  55. // Allowed values are: "year", "quarter", "month", "week", "day",
  56. // "hour", "minute". It also supports time settings like "1.5h"
  57. // (up to "w" for weeks).
  58. func (a *DateHistogramAggregation) Interval(interval string) *DateHistogramAggregation {
  59. a.interval = interval
  60. return a
  61. }
  62. // Order specifies the sort order. Valid values for order are:
  63. // "_key", "_count", a sub-aggregation name, or a sub-aggregation name
  64. // with a metric.
  65. func (a *DateHistogramAggregation) Order(order string, asc bool) *DateHistogramAggregation {
  66. a.order = order
  67. a.orderAsc = asc
  68. return a
  69. }
  70. func (a *DateHistogramAggregation) OrderByCount(asc bool) *DateHistogramAggregation {
  71. // "order" : { "_count" : "asc" }
  72. a.order = "_count"
  73. a.orderAsc = asc
  74. return a
  75. }
  76. func (a *DateHistogramAggregation) OrderByCountAsc() *DateHistogramAggregation {
  77. return a.OrderByCount(true)
  78. }
  79. func (a *DateHistogramAggregation) OrderByCountDesc() *DateHistogramAggregation {
  80. return a.OrderByCount(false)
  81. }
  82. func (a *DateHistogramAggregation) OrderByKey(asc bool) *DateHistogramAggregation {
  83. // "order" : { "_key" : "asc" }
  84. a.order = "_key"
  85. a.orderAsc = asc
  86. return a
  87. }
  88. func (a *DateHistogramAggregation) OrderByKeyAsc() *DateHistogramAggregation {
  89. return a.OrderByKey(true)
  90. }
  91. func (a *DateHistogramAggregation) OrderByKeyDesc() *DateHistogramAggregation {
  92. return a.OrderByKey(false)
  93. }
  94. // OrderByAggregation creates a bucket ordering strategy which sorts buckets
  95. // based on a single-valued calc get.
  96. func (a *DateHistogramAggregation) OrderByAggregation(aggName string, asc bool) *DateHistogramAggregation {
  97. // {
  98. // "aggs" : {
  99. // "genders" : {
  100. // "terms" : {
  101. // "field" : "gender",
  102. // "order" : { "avg_height" : "desc" }
  103. // },
  104. // "aggs" : {
  105. // "avg_height" : { "avg" : { "field" : "height" } }
  106. // }
  107. // }
  108. // }
  109. // }
  110. a.order = aggName
  111. a.orderAsc = asc
  112. return a
  113. }
  114. // OrderByAggregationAndMetric creates a bucket ordering strategy which
  115. // sorts buckets based on a multi-valued calc get.
  116. func (a *DateHistogramAggregation) OrderByAggregationAndMetric(aggName, metric string, asc bool) *DateHistogramAggregation {
  117. // {
  118. // "aggs" : {
  119. // "genders" : {
  120. // "terms" : {
  121. // "field" : "gender",
  122. // "order" : { "height_stats.avg" : "desc" }
  123. // },
  124. // "aggs" : {
  125. // "height_stats" : { "stats" : { "field" : "height" } }
  126. // }
  127. // }
  128. // }
  129. // }
  130. a.order = aggName + "." + metric
  131. a.orderAsc = asc
  132. return a
  133. }
  134. // MinDocCount sets the minimum document count per bucket.
  135. // Buckets with less documents than this min value will not be returned.
  136. func (a *DateHistogramAggregation) MinDocCount(minDocCount int64) *DateHistogramAggregation {
  137. a.minDocCount = &minDocCount
  138. return a
  139. }
  140. // TimeZone sets the timezone in which to translate dates before computing buckets.
  141. func (a *DateHistogramAggregation) TimeZone(timeZone string) *DateHistogramAggregation {
  142. a.timeZone = timeZone
  143. return a
  144. }
  145. // Format sets the format to use for dates.
  146. func (a *DateHistogramAggregation) Format(format string) *DateHistogramAggregation {
  147. a.format = format
  148. return a
  149. }
  150. // Offset sets the offset of time intervals in the histogram, e.g. "+6h".
  151. func (a *DateHistogramAggregation) Offset(offset string) *DateHistogramAggregation {
  152. a.offset = offset
  153. return a
  154. }
  155. // ExtendedBounds accepts int, int64, string, or time.Time values.
  156. // In case the lower value in the histogram would be greater than min or the
  157. // upper value would be less than max, empty buckets will be generated.
  158. func (a *DateHistogramAggregation) ExtendedBounds(min, max interface{}) *DateHistogramAggregation {
  159. a.extendedBoundsMin = min
  160. a.extendedBoundsMax = max
  161. return a
  162. }
  163. // ExtendedBoundsMin accepts int, int64, string, or time.Time values.
  164. func (a *DateHistogramAggregation) ExtendedBoundsMin(min interface{}) *DateHistogramAggregation {
  165. a.extendedBoundsMin = min
  166. return a
  167. }
  168. // ExtendedBoundsMax accepts int, int64, string, or time.Time values.
  169. func (a *DateHistogramAggregation) ExtendedBoundsMax(max interface{}) *DateHistogramAggregation {
  170. a.extendedBoundsMax = max
  171. return a
  172. }
  173. // Keyed specifies whether to return the results with a keyed response (or not).
  174. // See https://www.elastic.co/guide/en/elasticsearch/reference/5.6/search-aggregations-bucket-datehistogram-aggregation.html#_keyed_response_3.
  175. func (a *DateHistogramAggregation) Keyed(keyed bool) *DateHistogramAggregation {
  176. a.keyed = &keyed
  177. return a
  178. }
  179. func (a *DateHistogramAggregation) Source() (interface{}, error) {
  180. // Example:
  181. // {
  182. // "aggs" : {
  183. // "articles_over_time" : {
  184. // "date_histogram" : {
  185. // "field" : "date",
  186. // "interval" : "month"
  187. // }
  188. // }
  189. // }
  190. // }
  191. //
  192. // This method returns only the { "date_histogram" : { ... } } part.
  193. source := make(map[string]interface{})
  194. opts := make(map[string]interface{})
  195. source["date_histogram"] = opts
  196. // ValuesSourceAggregationBuilder
  197. if a.field != "" {
  198. opts["field"] = a.field
  199. }
  200. if a.script != nil {
  201. src, err := a.script.Source()
  202. if err != nil {
  203. return nil, err
  204. }
  205. opts["script"] = src
  206. }
  207. if a.missing != nil {
  208. opts["missing"] = a.missing
  209. }
  210. opts["interval"] = a.interval
  211. if a.minDocCount != nil {
  212. opts["min_doc_count"] = *a.minDocCount
  213. }
  214. if a.order != "" {
  215. o := make(map[string]interface{})
  216. if a.orderAsc {
  217. o[a.order] = "asc"
  218. } else {
  219. o[a.order] = "desc"
  220. }
  221. opts["order"] = o
  222. }
  223. if a.timeZone != "" {
  224. opts["time_zone"] = a.timeZone
  225. }
  226. if a.offset != "" {
  227. opts["offset"] = a.offset
  228. }
  229. if a.format != "" {
  230. opts["format"] = a.format
  231. }
  232. if a.extendedBoundsMin != nil || a.extendedBoundsMax != nil {
  233. bounds := make(map[string]interface{})
  234. if a.extendedBoundsMin != nil {
  235. bounds["min"] = a.extendedBoundsMin
  236. }
  237. if a.extendedBoundsMax != nil {
  238. bounds["max"] = a.extendedBoundsMax
  239. }
  240. opts["extended_bounds"] = bounds
  241. }
  242. if a.keyed != nil {
  243. opts["keyed"] = *a.keyed
  244. }
  245. // AggregationBuilder (SubAggregations)
  246. if len(a.subAggregations) > 0 {
  247. aggsMap := make(map[string]interface{})
  248. source["aggregations"] = aggsMap
  249. for name, aggregate := range a.subAggregations {
  250. src, err := aggregate.Source()
  251. if err != nil {
  252. return nil, err
  253. }
  254. aggsMap[name] = src
  255. }
  256. }
  257. // Add Meta data if available
  258. if len(a.meta) > 0 {
  259. source["meta"] = a.meta
  260. }
  261. return source, nil
  262. }