search_aggs_pipeline_mov_avg.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393
  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. // MovAvgAggregation operates on a series of data. It will slide a window
  6. // across the data and emit the average value of that window.
  7. //
  8. // For more details, see
  9. // https://www.elastic.co/guide/en/elasticsearch/reference/5.2/search-aggregations-pipeline-movavg-aggregation.html
  10. type MovAvgAggregation struct {
  11. format string
  12. gapPolicy string
  13. model MovAvgModel
  14. window *int
  15. predict *int
  16. minimize *bool
  17. subAggregations map[string]Aggregation
  18. meta map[string]interface{}
  19. bucketsPaths []string
  20. }
  21. // NewMovAvgAggregation creates and initializes a new MovAvgAggregation.
  22. func NewMovAvgAggregation() *MovAvgAggregation {
  23. return &MovAvgAggregation{
  24. subAggregations: make(map[string]Aggregation),
  25. bucketsPaths: make([]string, 0),
  26. }
  27. }
  28. func (a *MovAvgAggregation) Format(format string) *MovAvgAggregation {
  29. a.format = format
  30. return a
  31. }
  32. // GapPolicy defines what should be done when a gap in the series is discovered.
  33. // Valid values include "insert_zeros" or "skip". Default is "insert_zeros".
  34. func (a *MovAvgAggregation) GapPolicy(gapPolicy string) *MovAvgAggregation {
  35. a.gapPolicy = gapPolicy
  36. return a
  37. }
  38. // GapInsertZeros inserts zeros for gaps in the series.
  39. func (a *MovAvgAggregation) GapInsertZeros() *MovAvgAggregation {
  40. a.gapPolicy = "insert_zeros"
  41. return a
  42. }
  43. // GapSkip skips gaps in the series.
  44. func (a *MovAvgAggregation) GapSkip() *MovAvgAggregation {
  45. a.gapPolicy = "skip"
  46. return a
  47. }
  48. // Model is used to define what type of moving average you want to use
  49. // in the series.
  50. func (a *MovAvgAggregation) Model(model MovAvgModel) *MovAvgAggregation {
  51. a.model = model
  52. return a
  53. }
  54. // Window sets the window size for the moving average. This window will
  55. // "slide" across the series, and the values inside that window will
  56. // be used to calculate the moving avg value.
  57. func (a *MovAvgAggregation) Window(window int) *MovAvgAggregation {
  58. a.window = &window
  59. return a
  60. }
  61. // Predict sets the number of predictions that should be returned.
  62. // Each prediction will be spaced at the intervals in the histogram.
  63. // E.g. a predict of 2 will return two new buckets at the end of the
  64. // histogram with the predicted values.
  65. func (a *MovAvgAggregation) Predict(numPredictions int) *MovAvgAggregation {
  66. a.predict = &numPredictions
  67. return a
  68. }
  69. // Minimize determines if the model should be fit to the data using a
  70. // cost minimizing algorithm.
  71. func (a *MovAvgAggregation) Minimize(minimize bool) *MovAvgAggregation {
  72. a.minimize = &minimize
  73. return a
  74. }
  75. // SubAggregation adds a sub-aggregation to this aggregation.
  76. func (a *MovAvgAggregation) SubAggregation(name string, subAggregation Aggregation) *MovAvgAggregation {
  77. a.subAggregations[name] = subAggregation
  78. return a
  79. }
  80. // Meta sets the meta data to be included in the aggregation response.
  81. func (a *MovAvgAggregation) Meta(metaData map[string]interface{}) *MovAvgAggregation {
  82. a.meta = metaData
  83. return a
  84. }
  85. // BucketsPath sets the paths to the buckets to use for this pipeline aggregator.
  86. func (a *MovAvgAggregation) BucketsPath(bucketsPaths ...string) *MovAvgAggregation {
  87. a.bucketsPaths = append(a.bucketsPaths, bucketsPaths...)
  88. return a
  89. }
  90. func (a *MovAvgAggregation) Source() (interface{}, error) {
  91. source := make(map[string]interface{})
  92. params := make(map[string]interface{})
  93. source["moving_avg"] = params
  94. if a.format != "" {
  95. params["format"] = a.format
  96. }
  97. if a.gapPolicy != "" {
  98. params["gap_policy"] = a.gapPolicy
  99. }
  100. if a.model != nil {
  101. params["model"] = a.model.Name()
  102. settings := a.model.Settings()
  103. if len(settings) > 0 {
  104. params["settings"] = settings
  105. }
  106. }
  107. if a.window != nil {
  108. params["window"] = *a.window
  109. }
  110. if a.predict != nil {
  111. params["predict"] = *a.predict
  112. }
  113. if a.minimize != nil {
  114. params["minimize"] = *a.minimize
  115. }
  116. // Add buckets paths
  117. switch len(a.bucketsPaths) {
  118. case 0:
  119. case 1:
  120. params["buckets_path"] = a.bucketsPaths[0]
  121. default:
  122. params["buckets_path"] = a.bucketsPaths
  123. }
  124. // AggregationBuilder (SubAggregations)
  125. if len(a.subAggregations) > 0 {
  126. aggsMap := make(map[string]interface{})
  127. source["aggregations"] = aggsMap
  128. for name, aggregate := range a.subAggregations {
  129. src, err := aggregate.Source()
  130. if err != nil {
  131. return nil, err
  132. }
  133. aggsMap[name] = src
  134. }
  135. }
  136. // Add Meta data if available
  137. if len(a.meta) > 0 {
  138. source["meta"] = a.meta
  139. }
  140. return source, nil
  141. }
  142. // -- Models for moving averages --
  143. // See https://www.elastic.co/guide/en/elasticsearch/reference/5.2/search-aggregations-pipeline-movavg-aggregation.html#_models
  144. // MovAvgModel specifies the model to use with the MovAvgAggregation.
  145. type MovAvgModel interface {
  146. Name() string
  147. Settings() map[string]interface{}
  148. }
  149. // -- EWMA --
  150. // EWMAMovAvgModel calculates an exponentially weighted moving average.
  151. //
  152. // For more details, see
  153. // https://www.elastic.co/guide/en/elasticsearch/reference/5.2/search-aggregations-pipeline-movavg-aggregation.html#_ewma_exponentially_weighted
  154. type EWMAMovAvgModel struct {
  155. alpha *float64
  156. }
  157. // NewEWMAMovAvgModel creates and initializes a new EWMAMovAvgModel.
  158. func NewEWMAMovAvgModel() *EWMAMovAvgModel {
  159. return &EWMAMovAvgModel{}
  160. }
  161. // Alpha controls the smoothing of the data. Alpha = 1 retains no memory
  162. // of past values (e.g. a random walk), while alpha = 0 retains infinite
  163. // memory of past values (e.g. the series mean). Useful values are somewhere
  164. // in between. Defaults to 0.5.
  165. func (m *EWMAMovAvgModel) Alpha(alpha float64) *EWMAMovAvgModel {
  166. m.alpha = &alpha
  167. return m
  168. }
  169. // Name of the model.
  170. func (m *EWMAMovAvgModel) Name() string {
  171. return "ewma"
  172. }
  173. // Settings of the model.
  174. func (m *EWMAMovAvgModel) Settings() map[string]interface{} {
  175. settings := make(map[string]interface{})
  176. if m.alpha != nil {
  177. settings["alpha"] = *m.alpha
  178. }
  179. return settings
  180. }
  181. // -- Holt linear --
  182. // HoltLinearMovAvgModel calculates a doubly exponential weighted moving average.
  183. //
  184. // For more details, see
  185. // https://www.elastic.co/guide/en/elasticsearch/reference/5.2/search-aggregations-pipeline-movavg-aggregation.html#_holt_linear
  186. type HoltLinearMovAvgModel struct {
  187. alpha *float64
  188. beta *float64
  189. }
  190. // NewHoltLinearMovAvgModel creates and initializes a new HoltLinearMovAvgModel.
  191. func NewHoltLinearMovAvgModel() *HoltLinearMovAvgModel {
  192. return &HoltLinearMovAvgModel{}
  193. }
  194. // Alpha controls the smoothing of the data. Alpha = 1 retains no memory
  195. // of past values (e.g. a random walk), while alpha = 0 retains infinite
  196. // memory of past values (e.g. the series mean). Useful values are somewhere
  197. // in between. Defaults to 0.5.
  198. func (m *HoltLinearMovAvgModel) Alpha(alpha float64) *HoltLinearMovAvgModel {
  199. m.alpha = &alpha
  200. return m
  201. }
  202. // Beta is equivalent to Alpha but controls the smoothing of the trend
  203. // instead of the data.
  204. func (m *HoltLinearMovAvgModel) Beta(beta float64) *HoltLinearMovAvgModel {
  205. m.beta = &beta
  206. return m
  207. }
  208. // Name of the model.
  209. func (m *HoltLinearMovAvgModel) Name() string {
  210. return "holt"
  211. }
  212. // Settings of the model.
  213. func (m *HoltLinearMovAvgModel) Settings() map[string]interface{} {
  214. settings := make(map[string]interface{})
  215. if m.alpha != nil {
  216. settings["alpha"] = *m.alpha
  217. }
  218. if m.beta != nil {
  219. settings["beta"] = *m.beta
  220. }
  221. return settings
  222. }
  223. // -- Holt Winters --
  224. // HoltWintersMovAvgModel calculates a triple exponential weighted moving average.
  225. //
  226. // For more details, see
  227. // https://www.elastic.co/guide/en/elasticsearch/reference/5.2/search-aggregations-pipeline-movavg-aggregation.html#_holt_winters
  228. type HoltWintersMovAvgModel struct {
  229. alpha *float64
  230. beta *float64
  231. gamma *float64
  232. period *int
  233. seasonalityType string
  234. pad *bool
  235. }
  236. // NewHoltWintersMovAvgModel creates and initializes a new HoltWintersMovAvgModel.
  237. func NewHoltWintersMovAvgModel() *HoltWintersMovAvgModel {
  238. return &HoltWintersMovAvgModel{}
  239. }
  240. // Alpha controls the smoothing of the data. Alpha = 1 retains no memory
  241. // of past values (e.g. a random walk), while alpha = 0 retains infinite
  242. // memory of past values (e.g. the series mean). Useful values are somewhere
  243. // in between. Defaults to 0.5.
  244. func (m *HoltWintersMovAvgModel) Alpha(alpha float64) *HoltWintersMovAvgModel {
  245. m.alpha = &alpha
  246. return m
  247. }
  248. // Beta is equivalent to Alpha but controls the smoothing of the trend
  249. // instead of the data.
  250. func (m *HoltWintersMovAvgModel) Beta(beta float64) *HoltWintersMovAvgModel {
  251. m.beta = &beta
  252. return m
  253. }
  254. func (m *HoltWintersMovAvgModel) Gamma(gamma float64) *HoltWintersMovAvgModel {
  255. m.gamma = &gamma
  256. return m
  257. }
  258. func (m *HoltWintersMovAvgModel) Period(period int) *HoltWintersMovAvgModel {
  259. m.period = &period
  260. return m
  261. }
  262. func (m *HoltWintersMovAvgModel) SeasonalityType(typ string) *HoltWintersMovAvgModel {
  263. m.seasonalityType = typ
  264. return m
  265. }
  266. func (m *HoltWintersMovAvgModel) Pad(pad bool) *HoltWintersMovAvgModel {
  267. m.pad = &pad
  268. return m
  269. }
  270. // Name of the model.
  271. func (m *HoltWintersMovAvgModel) Name() string {
  272. return "holt_winters"
  273. }
  274. // Settings of the model.
  275. func (m *HoltWintersMovAvgModel) Settings() map[string]interface{} {
  276. settings := make(map[string]interface{})
  277. if m.alpha != nil {
  278. settings["alpha"] = *m.alpha
  279. }
  280. if m.beta != nil {
  281. settings["beta"] = *m.beta
  282. }
  283. if m.gamma != nil {
  284. settings["gamma"] = *m.gamma
  285. }
  286. if m.period != nil {
  287. settings["period"] = *m.period
  288. }
  289. if m.pad != nil {
  290. settings["pad"] = *m.pad
  291. }
  292. if m.seasonalityType != "" {
  293. settings["type"] = m.seasonalityType
  294. }
  295. return settings
  296. }
  297. // -- Linear --
  298. // LinearMovAvgModel calculates a linearly weighted moving average, such
  299. // that older values are linearly less important. "Time" is determined
  300. // by position in collection.
  301. //
  302. // For more details, see
  303. // https://www.elastic.co/guide/en/elasticsearch/reference/5.2/search-aggregations-pipeline-movavg-aggregation.html#_linear
  304. type LinearMovAvgModel struct {
  305. }
  306. // NewLinearMovAvgModel creates and initializes a new LinearMovAvgModel.
  307. func NewLinearMovAvgModel() *LinearMovAvgModel {
  308. return &LinearMovAvgModel{}
  309. }
  310. // Name of the model.
  311. func (m *LinearMovAvgModel) Name() string {
  312. return "linear"
  313. }
  314. // Settings of the model.
  315. func (m *LinearMovAvgModel) Settings() map[string]interface{} {
  316. return nil
  317. }
  318. // -- Simple --
  319. // SimpleMovAvgModel calculates a simple unweighted (arithmetic) moving average.
  320. //
  321. // For more details, see
  322. // https://www.elastic.co/guide/en/elasticsearch/reference/5.2/search-aggregations-pipeline-movavg-aggregation.html#_simple
  323. type SimpleMovAvgModel struct {
  324. }
  325. // NewSimpleMovAvgModel creates and initializes a new SimpleMovAvgModel.
  326. func NewSimpleMovAvgModel() *SimpleMovAvgModel {
  327. return &SimpleMovAvgModel{}
  328. }
  329. // Name of the model.
  330. func (m *SimpleMovAvgModel) Name() string {
  331. return "simple"
  332. }
  333. // Settings of the model.
  334. func (m *SimpleMovAvgModel) Settings() map[string]interface{} {
  335. return nil
  336. }