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