ml-configuring-aggregations.asciidoc 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484
  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 but
  12. still significantly less than your total number of documents, use
  13. {ref}/search-aggregations-bucket-composite-aggregation.html[composite aggregations]
  14. experimental:[Support for composite aggregations inside datafeeds is currently experimental].
  15. [discrete]
  16. [[aggs-limits-dfeeds]]
  17. == Requirements and limitations
  18. There are some limitations to using aggregations in {dfeeds}.
  19. Your aggregation must include a `date_histogram` aggregation or a top level `composite` aggregation,
  20. which in turn must contain a `max` aggregation on the time field.
  21. This requirement ensures that the aggregated data is a time series and the timestamp
  22. of each bucket is the time of the last record in the bucket.
  23. IMPORTANT: The name of the aggregation and the name of the field that it
  24. operates on need to match, otherwise the aggregation doesn't work. For example,
  25. if you use a `max` aggregation on a time field called `responsetime`, the name
  26. of the aggregation must be also `responsetime`.
  27. You must consider the interval of the `date_histogram` or `composite`
  28. aggregation carefully. The bucket span of your {anomaly-job} must be divisible
  29. by the value of the `calendar_interval` or `fixed_interval` in your aggregation
  30. (with no remainder). If you specify a `frequency` for your {dfeed},
  31. it must also be divisible by this interval. {anomaly-jobs-cap} cannot use
  32. `date_histogram` or `composite` aggregations with an interval measured in months
  33. because the length of the month is not fixed; they can use weeks or smaller units.
  34. TIP: As a rule of thumb, if your detectors use <<ml-metric-functions,metric>> or
  35. <<ml-sum-functions,sum>> analytical functions, set the `date_histogram` or `composite`
  36. aggregation interval to a tenth of the bucket span. This suggestion creates
  37. finer, more granular time buckets, which are ideal for this type of analysis. If
  38. your detectors use <<ml-count-functions,count>> or <<ml-rare-functions,rare>>
  39. functions, set the interval to the same value as the bucket span.
  40. If your <<aggs-dfeeds,{dfeed} uses aggregations with nested `terms` aggs>> and
  41. model plot is not enabled for the {anomaly-job}, neither the **Single Metric
  42. Viewer** nor the **Anomaly Explorer** can plot and display an anomaly
  43. chart for the job. In these cases, the charts are not visible and an explanatory
  44. message is shown.
  45. Your {dfeed} can contain multiple aggregations, but only the ones with names
  46. that match values in the job configuration are fed to the job.
  47. [discrete]
  48. [[aggs-using-date-histogram]]
  49. === Including aggregations in {anomaly-jobs}
  50. When you create or update an {anomaly-job}, you can include the names of
  51. aggregations, for example:
  52. [source,console]
  53. ----------------------------------
  54. PUT _ml/anomaly_detectors/farequote
  55. {
  56. "analysis_config": {
  57. "bucket_span": "60m",
  58. "detectors": [{
  59. "function": "mean",
  60. "field_name": "responsetime", <1>
  61. "by_field_name": "airline" <1>
  62. }],
  63. "summary_count_field_name": "doc_count"
  64. },
  65. "data_description": {
  66. "time_field":"time" <1>
  67. }
  68. }
  69. ----------------------------------
  70. // TEST[skip:setup:farequote_data]
  71. <1> The `airline`, `responsetime`, and `time` fields are aggregations. Only the
  72. aggregated fields defined in the `analysis_config` object are analyzed by the
  73. {anomaly-job}.
  74. NOTE: When the `summary_count_field_name` property is set to a non-null value,
  75. the job expects to receive aggregated input. The property must be set to the
  76. name of the field that contains the count of raw data points that have been
  77. aggregated. It applies to all detectors in the job.
  78. The aggregations are defined in the {dfeed} as follows:
  79. [source,console]
  80. ----------------------------------
  81. PUT _ml/datafeeds/datafeed-farequote
  82. {
  83. "job_id":"farequote",
  84. "indices": ["farequote"],
  85. "aggregations": {
  86. "buckets": {
  87. "date_histogram": {
  88. "field": "time",
  89. "fixed_interval": "360s",
  90. "time_zone": "UTC"
  91. },
  92. "aggregations": {
  93. "time": { <1>
  94. "max": {"field": "time"}
  95. },
  96. "airline": { <2>
  97. "terms": {
  98. "field": "airline",
  99. "size": 100
  100. },
  101. "aggregations": {
  102. "responsetime": { <3>
  103. "avg": {
  104. "field": "responsetime"
  105. }
  106. }
  107. }
  108. }
  109. }
  110. }
  111. }
  112. }
  113. ----------------------------------
  114. // TEST[skip:setup:farequote_job]
  115. <1> The aggregations have names that match the fields that they operate on. The
  116. `max` aggregation is named `time` and its field also needs to be `time`.
  117. <2> The `term` aggregation is named `airline` and its field is also named
  118. `airline`.
  119. <3> The `avg` aggregation is named `responsetime` and its field is also named
  120. `responsetime`.
  121. TIP: If you are using a `term` aggregation to gather influencer or partition
  122. field information, consider using a `composite` aggregation. It performs
  123. better than a `date_histogram` with a nested `term` aggregation and also includes
  124. all the values of the field instead of the top values per bucket.
  125. [discrete]
  126. [[aggs-using-composite]]
  127. === Using composite aggregations in {anomaly-jobs}
  128. experimental::[]
  129. For `composite` aggregation support, there must be exactly one `date_histogram` value
  130. source. That value source must not be sorted in descending order. Additional
  131. `composite` aggregation value sources are allowed, such as `terms`.
  132. NOTE: A {dfeed} that uses composite aggregations may not be as performant as datafeeds that use scrolling or
  133. date histogram aggregations. Composite aggregations are optimized
  134. for queries that are either `match_all` or `range` filters. Other types of
  135. queries may cause the `composite` aggregation to be ineffecient.
  136. Here is an example that uses a `composite` aggregation instead of a
  137. `date_histogram`.
  138. Assuming the same job configuration as above.
  139. [source,console]
  140. ----------------------------------
  141. PUT _ml/anomaly_detectors/farequote-composite
  142. {
  143. "analysis_config": {
  144. "bucket_span": "60m",
  145. "detectors": [{
  146. "function": "mean",
  147. "field_name": "responsetime",
  148. "by_field_name": "airline"
  149. }],
  150. "summary_count_field_name": "doc_count"
  151. },
  152. "data_description": {
  153. "time_field":"time"
  154. }
  155. }
  156. ----------------------------------
  157. // TEST[skip:setup:farequote_data]
  158. This is an example of a datafeed that uses a `composite` aggregation to bucket
  159. the metrics based on time and terms:
  160. [source,console]
  161. ----------------------------------
  162. PUT _ml/datafeeds/datafeed-farequote-composite
  163. {
  164. "job_id": "farequote-composite",
  165. "indices": [
  166. "farequote"
  167. ],
  168. "aggregations": {
  169. "buckets": {
  170. "composite": {
  171. "size": 1000, <1>
  172. "sources": [
  173. {
  174. "time_bucket": { <2>
  175. "date_histogram": {
  176. "field": "time",
  177. "fixed_interval": "360s",
  178. "time_zone": "UTC"
  179. }
  180. }
  181. },
  182. {
  183. "airline": { <3>
  184. "terms": {
  185. "field": "airline"
  186. }
  187. }
  188. }
  189. ]
  190. },
  191. "aggregations": {
  192. "time": { <4>
  193. "max": {
  194. "field": "time"
  195. }
  196. },
  197. "responsetime": { <5>
  198. "avg": {
  199. "field": "responsetime"
  200. }
  201. }
  202. }
  203. }
  204. }
  205. }
  206. ----------------------------------
  207. // TEST[skip:setup:farequote_job]
  208. <1> Provide the `size` to the composite agg to control how many resources
  209. are used when aggregating the data. A larger `size` means a faster datafeed but
  210. more cluster resources are used when searching.
  211. <2> The required `date_histogram` composite aggregation source. Make sure it
  212. is named differently than your desired time field.
  213. <3> Instead of using a regular `term` aggregation, adding a composite
  214. aggregation `term` source with the name `airline` works. Note its name
  215. is the same as the field.
  216. <4> The required `max` aggregation whose name is the time field in the
  217. job analysis config.
  218. <5> The `avg` aggregation is named `responsetime` and its field is also named
  219. `responsetime`.
  220. [discrete]
  221. [[aggs-dfeeds]]
  222. == Nested aggregations in {dfeeds}
  223. {dfeeds-cap} support complex nested aggregations. This example uses the
  224. `derivative` pipeline aggregation to find the first order derivative of the
  225. counter `system.network.out.bytes` for each value of the field `beat.name`.
  226. NOTE: `derivative` or other pipeline aggregations may not work within `composite`
  227. aggregations. See
  228. {ref}/search-aggregations-bucket-composite-aggregation.html#search-aggregations-bucket-composite-aggregation-pipeline-aggregations[composite aggregations and pipeline aggregations].
  229. [source,js]
  230. ----------------------------------
  231. "aggregations": {
  232. "beat.name": {
  233. "terms": {
  234. "field": "beat.name"
  235. },
  236. "aggregations": {
  237. "buckets": {
  238. "date_histogram": {
  239. "field": "@timestamp",
  240. "fixed_interval": "5m"
  241. },
  242. "aggregations": {
  243. "@timestamp": {
  244. "max": {
  245. "field": "@timestamp"
  246. }
  247. },
  248. "bytes_out_average": {
  249. "avg": {
  250. "field": "system.network.out.bytes"
  251. }
  252. },
  253. "bytes_out_derivative": {
  254. "derivative": {
  255. "buckets_path": "bytes_out_average"
  256. }
  257. }
  258. }
  259. }
  260. }
  261. }
  262. }
  263. ----------------------------------
  264. // NOTCONSOLE
  265. [discrete]
  266. [[aggs-single-dfeeds]]
  267. == Single bucket aggregations in {dfeeds}
  268. {dfeeds-cap} not only supports multi-bucket aggregations, but also single bucket
  269. aggregations. The following shows two `filter` aggregations, each gathering the
  270. number of unique entries for the `error` field.
  271. [source,js]
  272. ----------------------------------
  273. {
  274. "job_id":"servers-unique-errors",
  275. "indices": ["logs-*"],
  276. "aggregations": {
  277. "buckets": {
  278. "date_histogram": {
  279. "field": "time",
  280. "interval": "360s",
  281. "time_zone": "UTC"
  282. },
  283. "aggregations": {
  284. "time": {
  285. "max": {"field": "time"}
  286. }
  287. "server1": {
  288. "filter": {"term": {"source": "server-name-1"}},
  289. "aggregations": {
  290. "server1_error_count": {
  291. "value_count": {
  292. "field": "error"
  293. }
  294. }
  295. }
  296. },
  297. "server2": {
  298. "filter": {"term": {"source": "server-name-2"}},
  299. "aggregations": {
  300. "server2_error_count": {
  301. "value_count": {
  302. "field": "error"
  303. }
  304. }
  305. }
  306. }
  307. }
  308. }
  309. }
  310. }
  311. ----------------------------------
  312. // NOTCONSOLE
  313. [discrete]
  314. [[aggs-define-dfeeds]]
  315. == Defining aggregations in {dfeeds}
  316. When you define an aggregation in a {dfeed}, it must have one of the following forms:
  317. When using a `date_histogram` aggregation to bucket by time:
  318. [source,js]
  319. ----------------------------------
  320. "aggregations": {
  321. ["bucketing_aggregation": {
  322. "bucket_agg": {
  323. ...
  324. },
  325. "aggregations": {]
  326. "data_histogram_aggregation": {
  327. "date_histogram": {
  328. "field": "time",
  329. },
  330. "aggregations": {
  331. "timestamp": {
  332. "max": {
  333. "field": "time"
  334. }
  335. },
  336. [,"<first_term>": {
  337. "terms":{...
  338. }
  339. [,"aggregations" : {
  340. [<sub_aggregation>]+
  341. } ]
  342. }]
  343. }
  344. }
  345. }
  346. }
  347. }
  348. ----------------------------------
  349. // NOTCONSOLE
  350. When using a `composite` aggregation:
  351. [source,js]
  352. ----------------------------------
  353. "aggregations": {
  354. "composite_agg": {
  355. "sources": [
  356. {
  357. "date_histogram_agg": {
  358. "field": "time",
  359. ...settings...
  360. }
  361. },
  362. ...other valid sources...
  363. ],
  364. ...composite agg settings...,
  365. "aggregations": {
  366. "timestamp": {
  367. "max": {
  368. "field": "time"
  369. }
  370. },
  371. ...other aggregations...
  372. [
  373. [,"aggregations" : {
  374. [<sub_aggregation>]+
  375. } ]
  376. }]
  377. }
  378. }
  379. }
  380. ----------------------------------
  381. // NOTCONSOLE
  382. The top level aggregation must be exclusively one of the following:
  383. * A {ref}/search-aggregations-bucket.html[bucket aggregation] containing a single
  384. sub-aggregation that is a `date_histogram`
  385. * A top level aggregation that is a `date_histogram`
  386. * A top level aggregation is a `composite` aggregation
  387. There must be exactly one `date_histogram`, `composite` aggregation. For more information, see
  388. {ref}/search-aggregations-bucket-datehistogram-aggregation.html[Date histogram aggregation] and
  389. {ref}/search-aggregations-bucket-composite-aggregation.html[Composite aggregation].
  390. NOTE: The `time_zone` parameter in the date histogram aggregation must be set to
  391. `UTC`, which is the default value.
  392. Each histogram or composite bucket has a key, which is the bucket start time.
  393. This key cannot be used for aggregations in {dfeeds}, however, because
  394. they need to know the time of the latest record within a bucket.
  395. Otherwise, when you restart a {dfeed}, it continues from the start time of the
  396. histogram or composite bucket and possibly fetches the same data twice.
  397. The max aggregation for the time field is therefore necessary to provide
  398. the time of the latest record within a bucket.
  399. You can optionally specify a terms aggregation, which creates buckets for
  400. different values of a field.
  401. IMPORTANT: If you use a terms aggregation, by default it returns buckets for
  402. the top ten terms. Thus if the cardinality of the term is greater than 10, not
  403. all terms are analyzed. In this case, consider using `composite` aggregations
  404. experimental:[Support for composite aggregations inside datafeeds is currently experimental].
  405. You can change this behavior by setting the `size` parameter. To
  406. determine the cardinality of your data, you can run searches such as:
  407. [source,js]
  408. --------------------------------------------------
  409. GET .../_search
  410. {
  411. "aggs": {
  412. "service_cardinality": {
  413. "cardinality": {
  414. "field": "service"
  415. }
  416. }
  417. }
  418. }
  419. --------------------------------------------------
  420. // NOTCONSOLE
  421. By default, {es} limits the maximum number of terms returned to 10000. For high
  422. cardinality fields, the query might not run. It might return errors related to
  423. circuit breaking exceptions that indicate that the data is too large. In such
  424. cases, use `composite` aggregations in your {dfeed}. For more information, see
  425. {ref}/search-aggregations-bucket-terms-aggregation.html[Terms aggregation].
  426. You can also optionally specify multiple sub-aggregations. The sub-aggregations
  427. are aggregated for the buckets that were created by their parent aggregation.
  428. For more information, see {ref}/search-aggregations.html[Aggregations].