Elasticsearch 去重查询
1、前言
最近遇到一个 es 数据查询去重的需求,我这边需要的是获取去重后的结果,查询官网资料和各位大神的经验后,总结一下 elasticsearch 去重查询功能。
2、Elasticsearch 去重功能
- 关系型数据库中,比如 MySQL,可以通过 distinct 进行去重,一般分为两种:
- 1 ) 统计去重后的数量
select distinct(count(1)) from test;
- 2 ) 获取去重后的结果
select distinct name,sex from person;
test,person 为对应的表名。
- 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" } }
方式二较方式一:
- 简化;
- 性能好很多。
本文来自博客园,作者:游走De提莫,转载请注明原文链接:https://www.cnblogs.com/Gaimo/p/16036926.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)