es的聚合查询分析


 
 
聚合结果分析:
                聚合查询,结果包括两部分,一个是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 |
| 367 | 374 |
| 361 | 373 |
| 410 | 372 |
| 411 | 372 |
| 412 | 367 |
| 368 | 363 |
| 413 | 360 |
| 414 | 356 |
| 417 | 354 |
| 415 | 346 |
| 409 | 346 |
| 416 | 345 |
| 401 | 317 |
| 418 | 316 |
| 389 | 305 |
| 390 | 304 |
| 394 | 299 |
| 392 | 296 |
| 405 | 289 |
| 404 | 288 |
| 385 | 286 |
| 399 | 284 |
| 403 | 283 |
| 406 | 283 |
| 402 | 283 |
| 400 | 282 |
| 391 | 279 |
| 388 | 276 |
| 407 | 276 |
| 386 | 273 |
| 398 | 272 |
| 393 | 266 |
| 387 | 254 |
| 374 | 113 |
| 378 | 106 |
| 381 | 103 |
| 375 |  98 |
| 380 |  98 |
| 377 |  97 |
| 376 |  91 |
| 382 |  89 |
| 379 |  87 |
| 373 |  81 |
+-----+-----+
60 rows in set (1.02 sec)
 
 
 
ES默认查询结果:
[root@jiangmin ~]# curl -X GET 'localhost:9200/node_file_viruses/_search?pretty' -H 'Content-Type:application/json'  -d '{
>     "size":0,                                             ------------->   定义满足以下聚合查询的返回数据
>     "aggs":{
>         "seven_range":{
>             "range":{
>                 "field": "find_time",
>                 "ranges": [ {"from": 1567624289,"to":1568229089} ]
>             },
>             "aggs":{
>                 "client":{
>                     "terms":{
>                         "size": 10,                                 ---》定义每个分片,返回的聚合数量,默认从大到小排序
>                         "field": "nid"
>                     }
>                 }
>             }
>         }
>     },
>     "query":{
>         "bool":{
>             "must":[
>                     {
>                         "term":{
>                                   "virus_findby": 20
>                                }
>                     }
>                    ]
>         }
>     }
> }'
{
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 252359,
    "max_score" : 0.0,
    "hits" : [ ]
  },
  "aggregations" : {
    "seven_range" : {
      "buckets" : [
        {
          "key" : "1.567624289E9-1.568229089E9",
          "from" : 1.567624289E9,
          "to" : 1.568229089E9,
          "doc_count" : 18215,
          "client" : {
            "doc_count_error_upper_bound" : 347,
            "sum_other_doc_count" : 14157,
            "buckets" : [
              {
                "key" : 426,
                "doc_count" : 440
              },
              {
                "key" : 422,
                "doc_count" : 432
              },
              {
                "key" : 430,
                "doc_count" : 424
              },
              {
                "key" : 359,
                "doc_count" : 408
              },
              {
                "key" : 366,
                "doc_count" : 406
              },
              {
                "key" : 421,
                "doc_count" : 403
              },
              {
                "key" : 423,
                "doc_count" : 395
              },
              {
                "key" : 425,
                "doc_count" : 385
              },
              {
                "key" : 362,
                "doc_count" : 384
              },
              {
                "key" : 363,
                "doc_count" : 381
              }
            ]
          }
        }
      ]
    }
  }
}
 
通过以上对比发现,桶聚合和Mysql group by的值有差距,如nid428的数据,使用es查询时就出现遗漏。
分析可知道,es中的数据,是存在不同的分片中,当要查询数据时,各个分片,按照聚合原则,取出最多的前十条,最后将所有分片的数据整合,得到最终的数据。
这里,可能出现了nid=428的数据,在某个分片或者多个分片中,排序不在前十,因此最终汇总时,出现数据偏差。
可以通过修改聚合时,每个桶的排序数,而得到正确数据
 
 
通过修改es聚合排序数量,得到更精确的数据
        以下,通过修改term聚合的返回数量,得到了与mysql查询更接近的结果
[root@jiangmin ~]# curl -X GET 'localhost:9200/node_file_viruses/_search?pretty' -H 'Content-Type:application/json'  -d '{
>     "size":0,
>     "aggs":{
>         "seven_range":{
>             "range":{
>                 "field": "find_time",
>                 "ranges": [ {"from": 1567624289,"to":1568229089} ]
>             },
>             "aggs":{
>                 "client":{
>                     "terms":{
>                         "size": 20,
>                         "field": "nid"
>                     }
>                 }
>             }
>         }
>     },
>     "query":{
>         "bool":{
>             "must":[
>                     {
>                         "term":{
>                                   "virus_findby": 20
>                                }
>                     }
>                    ]
>         }
>     }
> }'
{
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 252359,
    "max_score" : 0.0,
    "hits" : [ ]
  },
  "aggregations" : {
    "seven_range" : {
      "buckets" : [
        {
          "key" : "1.567624289E9-1.568229089E9",
          "from" : 1.567624289E9,
          "to" : 1.568229089E9,
          "doc_count" : 18215,
          "client" : {
            "doc_count_error_upper_bound" : 280,
            "sum_other_doc_count" : 10183,
            "buckets" : [
              {
                "key" : 426,
                "doc_count" : 440
              },
              {
                "key" : 422,
                "doc_count" : 432
              },
              {
                "key" : 428,
                "doc_count" : 425
              },
              {
                "key" : 427,
                "doc_count" : 424
              },
              {
                "key" : 430,
                "doc_count" : 424
              },
              {
                "key" : 424,
                "doc_count" : 423
              },
              {
                "key" : 359,
                "doc_count" : 408
              },
              {
                "key" : 366,
                "doc_count" : 406
              },
              {
                "key" : 360,
                "doc_count" : 403
              },
              {
                "key" : 421,
                "doc_count" : 403
              },
              {
                "key" : 429,
                "doc_count" : 399
              },
              {
                "key" : 365,
                "doc_count" : 398
              },
              {
                "key" : 423,
                "doc_count" : 395
              },
              {
                "key" : 425,
                "doc_count" : 385
              },
              {
                "key" : 362,
                "doc_count" : 384
              },
              {
                "key" : 364,
                "doc_count" : 383
              },
              {
                "key" : 363,
                "doc_count" : 381
              },
              {
                "key" : 367,
                "doc_count" : 374
              },
              {
                "key" : 361,
                "doc_count" : 373
              },
              {
                "key" : 410,
                "doc_count" : 372
              }
            ]
          }
        }
      ]
    }
  }
}
 
 
 
 
 
 
 
 
 
 
 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM