Elasticsearch6.X 去重
1、题记
Elasticsearch有没有类似mysql的distinct的去重功能呢?
1)如何去重计数?
类似mysql: select distinct(count(1)) from my_table;
2)如何获取去重结果。
类似mysql:SELECT DISTINCT name,age FROM users;
2、需求
1)对ES的检索结果进行去重统计计数。
2)对ES的检索结果去重后显示。
3、分析
1)统计计数需要借助ES聚合功能结合cardinality实现。
2)去重显示结果有两种方式:
方式一:使用字段聚合+top_hits聚合方式。
方式二:使用collapse折叠功能。
4、DSL源码
1)统计去重数目。
1GET books/_search
2{
3"size":0,
4"aggs" : {
5"books_count" : {
6"cardinality" : {
7"field" : "title.keyword"
8}
9}
10}
11}
2)返回去重内容
方式一:top_hits聚合
1GET books/_search
2{
3"query": {
4"match_all": {}
5},
6"aggs": {
7"type": {
8"terms": {
9"field": "title.keyword",
10"size": 10
11},
12"aggs": {
13"title_top": {
14"top_hits": {
15"_source": {
16"includes": ["title"]
17},
18"sort": [
19{
20"title.keyword": {
21"order": "desc"
22}
23}
24],
25"size":1
26}
27}
28}
29}
30},
31"size": 0
32}
方式二:折叠
1GET books/_search
2{
3"query": {
4"match_all":{}
5},
6"collapse": {
7"field": "title.keyword"
8}
9}
方式二较方式一:
1)简化;
2)性能比aggs的实现要好很多。
更多DSL详见:http://t.cn/RmafXMJ
5、注意事项&小结
-
折叠功能ES5.3版本之后才发布的。
-
针对字符串类型,聚合&折叠只能针对keyword类型有效
import datetime import json from elasticsearch import Elasticsearch es = Elasticsearch(['192.168.0.0:9200']) source_arr = ["fileName","flag"] def query_param(): time1=datetime.datetime.now() res = es.search(index="ccat1",doc_type='demo0',from_=0,size=100000, body={ "collapse": { "field": "fileName.keyword" }, "_source": source_arr,"query": {"bool": { "must": [ # {"match": {"captureInfo.currentDistinguishNum": 0}}, {"range": { "photo.capturenum": { "gte":0, "lte": 1 } } }, {"range": { "ymdh": { "gte": 2018072400, "lte": 2018072402 } } } ]} }}) # query = {'query': {'match_all': {}}}# 查找所有文档 print(len(res["hits"]["hits"])) for data in res["hits"]["hits"]: pass # print("http://192.168.0.100:",data["_source"]["uri"]) if __name__ == '__main__': query_param()