search_aggs_bucket_date_histogram.go 8.0 KB

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