聚合结果分析:
聚合查询,结果包括两部分,一个是hits,一个是aggregations.
另一部分:是查询情况显示,包括:took(查询消耗时间),time_out(是否超时),_shards(查询了几个分片,是否失败等)
“hits”:聚合查询的结果,默认按照分值排序。显示的每条内容,可以通过_source,store等参数控制
在使用json查询es时,最外层size控制了显示的条目数
"aggregations": 存储了聚合的最终结果
聚合查询的准确性分析
es在执行分桶查询时,会在每个分片下执行所有查询内容,最后在一个分片中将所有内容汇总,返回给客户端。这个过程中会存在数据误差。
es默认,每个分片返回的是前十条数据,以下为举例分析方便,自定义了一下返回结果,并做分析
如:使用term实现分组查询,并计算每个组的数目时,假如设定每个分片返回3条最多的数据,并最后汇总。
假定第一个分片依次是:
A:30 B:28 C:22 D:20 E:20
假定第二个分片依次是:
A:58 B:26 C:15 D:14 E:14
假定第三个分片依次是:
E:35 B:26 D:18 C:14 A:10
如以上数据:
假如每个分片返回最多的前三条数据,并送到汇总分片,去获取排名前三的:则排序依次是A:88 B:80 C:37
假如每个分片返回最多前的四条数据,并送到汇总分片,去获取排名前三的:则排序依次是A:88 B:80 D:52
假如每个分片返回最多前的五条数据,并送到汇总分片,去获取排名前三的:则排序依次是A:98 B:80 E:69
实际应用中,可以允许每个分片返回更多的数据,但相对而言,花费的时间就够多
聚合和分页查询
由已上可知,对聚合后的数据,做分页查询,是无法支持的。
聚合能够实现前十,前一百,前一千,但是无法支持分页,因为分页查询的本质是将所有数据进行统合后分析。其中第一个问题就是,每个分片之间会生成大量的结果,造成性能大幅降低。但是倘若不传全部的数据,而只是传递部分数据,则会造成,排名在后的,可能出现数据比排名靠前的还要大。因为本身聚合就有一定的误差。
MYSQL查询结果:
以下由于es中数据,比mysql少几条,因此使用id来控制范围,这个无关紧要
mysql> SELECT nid, count(nid) as cnt from node_file_viruses WHERE find_time >=1567624289 AND find_time < 1568229089 AND virus_findby =20 AND id< 3782070 GROUP BY nid ORDER BY cnt desc;
+-----+-----+
| nid | cnt |
+-----+-----+
| 426 | 440 |
| 422 | 432 |
| 428 | 425 |
| 430 | 424 |
| 427 | 424 |
| 424 | 423 |
| 359 | 408 |
| 366 | 406 |
| 360 | 403 |
| 421 | 403 |
| 429 | 399 |
| 365 | 398 |
| 423 | 395 |
| 425 | 385 |
| 362 | 384 |
| 364 | 383 |
| 363 | 381 |
| 36