• Elasticsearch 去重查询


    1、前言

    最近遇到一个 es 数据查询去重的需求,我这边需要的是获取去重后的结果,查询官网资料和各位大神的经验后,总结一下 elasticsearch 去重查询功能。

    2、Elasticsearch 去重功能

    1. 关系型数据库中,比如 MySQL,可以通过 distinct 进行去重,一般分为两种:
    • 1 ) 统计去重后的数量
    select distinct(count(1)) from test;
    
    • 2 ) 获取去重后的结果
    select distinct name,sex from person;
    

    test,person 为对应的表名。

    1. Elasticsearch 类似功能的实现方式
    • 1 ) es 查询结果进行去重计数

      es 的去重计数工卡可以通过 es 的聚合功能 + Cardinality 聚合函数来实现

    • 2 ) es 查询结果去重后显示

      去重显示有两种方式:

      (1) 使用字段聚合 + top_hits 聚合方式

      (2) 使用 collapse 折叠功能 (5.3 后版本提供)

      我这里使用的 es 是 2.4 的版本,JavaApi 使用的是第一种方式,5.x,6.x 的版本也可以使用

    3、DSL 源码

    可以通过 es head 插件来进行查询测试,user_onoffline_log 是有的索引名字,uid 是其中的一个字段,uid_aggs 是聚合的名字,可以随便自定义。

    1)统计去重数目。

    POST user_onoffline_log/_search
    {
      "query": {
        "match_all": {}
      },
      "size": 0,
      "aggs": {
        "uid_aggs": {
          "cardinality": {
            "field": "uid"
          }
        }
      }
    }
    
    

    结果:

    {
      "took": 565,
      "timed_out": false,
      "_shards": {
        "total": 5,
        "successful": 5,
        "failed": 0
      },
      "hits": {
        "total": 43326369,
        "max_score": 0,
        "hits": []
      },
      "aggregations": {
        "uid_aggs": {
          "value": 12243
        }
      }
    }
    

    可以看到 uid 字段去重后的计数值为 12243。

    2)返回去重内容

    方式一:top_hits 聚合

    POST /user_onoffline_log/
    {
      "query": {
        "match_all": {}
      },
      "aggs": {
        "uid_aggs": {
          "terms": {
            "field": "uid",
            "size": 1
          },
          "aggs": {
            "uid_top": {
              "top_hits": {
                "sort": [
                  {
                    "uid": {
                      "order": "desc"
                    }
                  }
                ],
                "size": 1
              }
            }
          }
        }
      },
      "size": 0
    }
    

    可以通过 size 设置显示的数量,上面 aggs 的 size 设置的 1,结果:

    {
        "took":2318,
        "timed_out":false,
        "_shards":{
            "total":200,
            "successful":5,
            "failed":195,
            "failures":[
                {
                    "shard":0,
                    "index":"stamgr-logstash-2018.03.06",
                    "node":"kUbpfLDMRLuAnloYBBRGng",
                    "reason":{
                        "type":"search_parse_exception",
                        "reason":"No mapping found for [uid] in order to sort on"
                    }
                }
            ]
        },
        "hits":{
            "total":43326369,
            "max_score":0,
            "hits":[
    
            ]
        },
        "aggregations":{
            "uid_aggs":{
                "doc_count_error_upper_bound":1909,
                "sum_other_doc_count":2174528,
                "buckets":[
                    {
                        "key":"",
                        "doc_count":41151839,
                        "uid_top":{
                            "hits":{
                                "total":41151839,
                                "max_score":null,
                                "hits":[
                                    {
                                        "_index":"user_onoffline_log",
                                        "_type":"logs",
                                        "_id":"AWYDAu4otdWc46rphdZz",
                                        "_score":null,
                                        "_source":{
                                            "uid":"",
                                            "ip":"",
                                            "mac":"00:5a:39:ec:1c:e4",
                                            "ap_serial_id_online":"219801A0REM173004134",
                                            "ap_mac_online":"9c:06:1b:a8:18:e0",
                                            "ap_name_online":"lFkFq_xiangyundao_sihailujiaokou_W-E_AP02",
                                            "location_online":"祥云道与四海路交口由西向东第2点",
                                            "zone_online":"祥云道",
                                            "ap_serial_id_offline":"219801A0REM173004692",
                                            "ap_mac_offline":"9c:06:1b:a8:00:00",
                                            "ap_name_offline":"lFkFq_xiangyundao_sihailujiaokou_W-E_AP03",
                                            "location_offline":"祥云道与四海路交口由西向东第3点",
                                            "zone_offline":"祥云道",
                                            "area":"开发区",
                                            "area_id":"001",
                                            "province":"",
                                            "city":"",
                                            "corp":"",
                                            "type":"3",
                                            "online_time":"201809222310",
                                            "offline_time":"201809230440",
                                            "duration":330
                                        },
                                        "sort":[
                                            ""
                                        ]
                                    }
                                ]
                            }
                        }
                    }
                ]
            }
        }
    }
    

    方式二:折叠

    POST /user_onoffline_log/
    {
        "query":{
            "match_all":{
    
            }
        },
        "collapse":{
            "field":"uid"
        }
    }
    

    方式二较方式一:

    • 简化;
    • 性能好很多。
  • 相关阅读:
    [洛谷P1507]NASA的食物计划 以及 对背包问题的整理
    [洛谷P3811]【模板】乘法逆元
    56级信息奥赛12学子汇总
    [洛谷U63006]导函数最小系数
    [洛谷U62364]三次函数极值
    [洛谷U62358]求导函数
    Nagios 请检查HTTP服务器关于该CGI的访问权限设置
    安装Cacti-plugin
    解压安装Cacti在apache中的补充
    64位操作系统下IIS报“试图加载格式不正确的程序”错误
  • 原文地址:https://www.cnblogs.com/Gaimo/p/16036926.html
Copyright © 2020-2023  润新知