ml-configuring-aggregations.asciidoc 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335
  1. [role="xpack"]
  2. [[ml-configuring-aggregation]]
  3. = Aggregating data for faster performance
  4. By default, {dfeeds} fetch data from {es} using search and scroll requests.
  5. It can be significantly more efficient, however, to aggregate data in {es}
  6. and to configure your {anomaly-jobs} to analyze aggregated data.
  7. One of the benefits of aggregating data this way is that {es} automatically
  8. distributes these calculations across your cluster. You can then feed this
  9. aggregated data into the {ml-features} instead of raw results, which
  10. reduces the volume of data that must be considered while detecting anomalies.
  11. TIP: If you use a terms aggregation and the cardinality of a term is high, the
  12. aggregation might not be effective and you might want to just use the default
  13. search and scroll behavior.
  14. [discrete]
  15. [[aggs-limits-dfeeds]]
  16. == Requirements and limitations
  17. There are some limitations to using aggregations in {dfeeds}. Your aggregation
  18. must include a `date_histogram` aggregation, which in turn must contain a `max`
  19. aggregation on the time field. This requirement ensures that the aggregated data
  20. is a time series and the timestamp of each bucket is the time of the last record
  21. in the bucket.
  22. IMPORTANT: The name of the aggregation and the name of the field that the agg
  23. operates on need to match, otherwise the aggregation doesn't work. For example,
  24. if you use a `max` aggregation on a time field called `responsetime`, the name
  25. of the aggregation must be also `responsetime`.
  26. You must also consider the interval of the date histogram aggregation carefully.
  27. The bucket span of your {anomaly-job} must be divisible by the value of the
  28. `calendar_interval` or `fixed_interval` in your aggregation (with no remainder).
  29. If you specify a `frequency` for your {dfeed}, it must also be divisible by this
  30. interval. {anomaly-jobs-cap} cannot use date histograms with an interval
  31. measured in months because the length of the month is not fixed. {dfeeds-cap}
  32. tolerate weeks or smaller units.
  33. TIP: As a rule of thumb, if your detectors use <<ml-metric-functions,metric>> or
  34. <<ml-sum-functions,sum>> analytical functions, set the date histogram
  35. aggregation interval to a tenth of the bucket span. This suggestion creates
  36. finer, more granular time buckets, which are ideal for this type of analysis. If
  37. your detectors use <<ml-count-functions,count>> or <<ml-rare-functions,rare>>
  38. functions, set the interval to the same value as the bucket span.
  39. If your <<aggs-dfeeds,{dfeed} uses aggregations with nested `terms` aggs>> and
  40. model plot is not enabled for the {anomaly-job}, neither the **Single Metric
  41. Viewer** nor the **Anomaly Explorer** can plot and display an anomaly
  42. chart for the job. In these cases, the charts are not visible and an explanatory
  43. message is shown.
  44. When the aggregation interval of the {dfeed} and the bucket span of the job
  45. don't match, the values of the chart plotted in both the **Single Metric
  46. Viewer** and the **Anomaly Explorer** differ from the actual values of the job.
  47. To avoid this behavior, make sure that the aggregation interval in the {dfeed}
  48. configuration and the bucket span in the {anomaly-job} configuration have the
  49. same values.
  50. [discrete]
  51. [[aggs-include-jobs]]
  52. == Including aggregations in {anomaly-jobs}
  53. When you create or update an {anomaly-job}, you can include the names of
  54. aggregations, for example:
  55. [source,console]
  56. ----------------------------------
  57. PUT _ml/anomaly_detectors/farequote
  58. {
  59. "analysis_config": {
  60. "bucket_span": "60m",
  61. "detectors": [{
  62. "function": "mean",
  63. "field_name": "responsetime", <1>
  64. "by_field_name": "airline" <1>
  65. }],
  66. "summary_count_field_name": "doc_count"
  67. },
  68. "data_description": {
  69. "time_field":"time" <1>
  70. }
  71. }
  72. ----------------------------------
  73. // TEST[skip:setup:farequote_data]
  74. <1> The `airline`, `responsetime`, and `time` fields are aggregations. Only the
  75. aggregated fields defined in the `analysis_config` object are analyzed by the
  76. {anomaly-job}.
  77. NOTE: When the `summary_count_field_name` property is set to a non-null value,
  78. the job expects to receive aggregated input. The property must be set to the
  79. name of the field that contains the count of raw data points that have been
  80. aggregated. It applies to all detectors in the job.
  81. The aggregations are defined in the {dfeed} as follows:
  82. [source,console]
  83. ----------------------------------
  84. PUT _ml/datafeeds/datafeed-farequote
  85. {
  86. "job_id":"farequote",
  87. "indices": ["farequote"],
  88. "aggregations": {
  89. "buckets": {
  90. "date_histogram": {
  91. "field": "time",
  92. "fixed_interval": "360s",
  93. "time_zone": "UTC"
  94. },
  95. "aggregations": {
  96. "time": { <1>
  97. "max": {"field": "time"}
  98. },
  99. "airline": { <2>
  100. "terms": {
  101. "field": "airline",
  102. "size": 100
  103. },
  104. "aggregations": {
  105. "responsetime": { <3>
  106. "avg": {
  107. "field": "responsetime"
  108. }
  109. }
  110. }
  111. }
  112. }
  113. }
  114. }
  115. }
  116. ----------------------------------
  117. // TEST[skip:setup:farequote_job]
  118. <1> The aggregations have names that match the fields that they operate on. The
  119. `max` aggregation is named `time` and its field also needs to be `time`.
  120. <2> The `term` aggregation is named `airline` and its field is also named
  121. `airline`.
  122. <3> The `avg` aggregation is named `responsetime` and its field is also named
  123. `responsetime`.
  124. Your {dfeed} can contain multiple aggregations, but only the ones with names
  125. that match values in the job configuration are fed to the job.
  126. [discrete]
  127. [[aggs-dfeeds]]
  128. == Nested aggregations in {dfeeds}
  129. {dfeeds-cap} support complex nested aggregations. This example uses the
  130. `derivative` pipeline aggregation to find the first order derivative of the
  131. counter `system.network.out.bytes` for each value of the field `beat.name`.
  132. [source,js]
  133. ----------------------------------
  134. "aggregations": {
  135. "beat.name": {
  136. "terms": {
  137. "field": "beat.name"
  138. },
  139. "aggregations": {
  140. "buckets": {
  141. "date_histogram": {
  142. "field": "@timestamp",
  143. "fixed_interval": "5m"
  144. },
  145. "aggregations": {
  146. "@timestamp": {
  147. "max": {
  148. "field": "@timestamp"
  149. }
  150. },
  151. "bytes_out_average": {
  152. "avg": {
  153. "field": "system.network.out.bytes"
  154. }
  155. },
  156. "bytes_out_derivative": {
  157. "derivative": {
  158. "buckets_path": "bytes_out_average"
  159. }
  160. }
  161. }
  162. }
  163. }
  164. }
  165. }
  166. ----------------------------------
  167. // NOTCONSOLE
  168. [discrete]
  169. [[aggs-single-dfeeds]]
  170. == Single bucket aggregations in {dfeeds}
  171. {dfeeds-cap} not only supports multi-bucket aggregations, but also single bucket
  172. aggregations. The following shows two `filter` aggregations, each gathering the
  173. number of unique entries for the `error` field.
  174. [source,js]
  175. ----------------------------------
  176. {
  177. "job_id":"servers-unique-errors",
  178. "indices": ["logs-*"],
  179. "aggregations": {
  180. "buckets": {
  181. "date_histogram": {
  182. "field": "time",
  183. "interval": "360s",
  184. "time_zone": "UTC"
  185. },
  186. "aggregations": {
  187. "time": {
  188. "max": {"field": "time"}
  189. }
  190. "server1": {
  191. "filter": {"term": {"source": "server-name-1"}},
  192. "aggregations": {
  193. "server1_error_count": {
  194. "value_count": {
  195. "field": "error"
  196. }
  197. }
  198. }
  199. },
  200. "server2": {
  201. "filter": {"term": {"source": "server-name-2"}},
  202. "aggregations": {
  203. "server2_error_count": {
  204. "value_count": {
  205. "field": "error"
  206. }
  207. }
  208. }
  209. }
  210. }
  211. }
  212. }
  213. }
  214. ----------------------------------
  215. // NOTCONSOLE
  216. [discrete]
  217. [[aggs-define-dfeeds]]
  218. == Defining aggregations in {dfeeds}
  219. When you define an aggregation in a {dfeed}, it must have the following form:
  220. [source,js]
  221. ----------------------------------
  222. "aggregations": {
  223. ["bucketing_aggregation": {
  224. "bucket_agg": {
  225. ...
  226. },
  227. "aggregations": {]
  228. "data_histogram_aggregation": {
  229. "date_histogram": {
  230. "field": "time",
  231. },
  232. "aggregations": {
  233. "timestamp": {
  234. "max": {
  235. "field": "time"
  236. }
  237. },
  238. [,"<first_term>": {
  239. "terms":{...
  240. }
  241. [,"aggregations" : {
  242. [<sub_aggregation>]+
  243. } ]
  244. }]
  245. }
  246. }
  247. }
  248. }
  249. }
  250. ----------------------------------
  251. // NOTCONSOLE
  252. The top level aggregation must be either a
  253. {ref}/search-aggregations-bucket.html[bucket aggregation] containing as single
  254. sub-aggregation that is a `date_histogram` or the top level aggregation is the
  255. required `date_histogram`. There must be exactly one `date_histogram`
  256. aggregation. For more information, see
  257. {ref}/search-aggregations-bucket-datehistogram-aggregation.html[Date histogram aggregation].
  258. NOTE: The `time_zone` parameter in the date histogram aggregation must be set to
  259. `UTC`, which is the default value.
  260. Each histogram bucket has a key, which is the bucket start time. This key cannot
  261. be used for aggregations in {dfeeds}, however, because they need to know the
  262. time of the latest record within a bucket. Otherwise, when you restart a
  263. {dfeed}, it continues from the start time of the histogram bucket and possibly
  264. fetches the same data twice. The max aggregation for the time field is therefore
  265. necessary to provide the time of the latest record within a bucket.
  266. You can optionally specify a terms aggregation, which creates buckets for
  267. different values of a field.
  268. IMPORTANT: If you use a terms aggregation, by default it returns buckets for
  269. the top ten terms. Thus if the cardinality of the term is greater than 10, not
  270. all terms are analyzed.
  271. You can change this behavior by setting the `size` parameter. To
  272. determine the cardinality of your data, you can run searches such as:
  273. [source,js]
  274. --------------------------------------------------
  275. GET .../_search
  276. {
  277. "aggs": {
  278. "service_cardinality": {
  279. "cardinality": {
  280. "field": "service"
  281. }
  282. }
  283. }
  284. }
  285. --------------------------------------------------
  286. // NOTCONSOLE
  287. By default, {es} limits the maximum number of terms returned to 10000. For high
  288. cardinality fields, the query might not run. It might return errors related to
  289. circuit breaking exceptions that indicate that the data is too large. In such
  290. cases, do not use aggregations in your {dfeed}. For more information, see
  291. {ref}/search-aggregations-bucket-terms-aggregation.html[Terms aggregation].
  292. You can also optionally specify multiple sub-aggregations. The sub-aggregations
  293. are aggregated for the buckets that were created by their parent aggregation.
  294. For more information, see {ref}/search-aggregations.html[Aggregations].