首页 > 其他分享 >elasticsearch中如何实现dinstinct去重功能

elasticsearch中如何实现dinstinct去重功能

时间:2022-12-07 20:08:38浏览次数:40  
标签:count index 功能 name doc age elasticsearch sql dinstinct


一、功能场景

在mysql数据库中查询数据时,我们可以采用dinstinct关键字去重。那么,在ES中如何实现查询结果去重呢?


二、原理分析

DISTINCT关键字去重的sql语句等价于对需要去重的字段进行GROUP BY。

以下2个sql都能实现对name,age字段查询结果的去重。

SELECT DISTINCT name,age FROM distinct_index

SELECT name,age FROM distinct_index GROUP BY name,age

三、方案汇总

根据上面的分析,总结出以下2种实现方案:
1、使用GROUP BY的SQL查询
2、使用Aggregation(聚合)查询
说明:
ES6.3之后的版本以及支持SQL查询

四、数据准备

## 删除索引
## DELETE distinct_index
## 新建索引
PUT distinct_index
{
"mappings": {
"properties": {
"name": {
"type": "keyword"
},
"age": {
"type": "integer"
}
}
}
}
## 添加数据
POST distinct_index/_bulk?refresh
{ "create": { } }
{ "name": "小天", "age": 25}
{ "create": { } }
{ "name": "小天", "age": 25}
{ "create": { } }
{ "name": "老万", "age": 35}
{ "create": { } }
{ "name": "老王", "age": 45}
{ "create": { } }
{ "name": "小明", "age": 15}
{ "create": { } }
{ "name": "小明", "age": 15}
{ "create": { } }
{ "name": "小红", "age": 12}
{ "create": { } }
{ "name": "乐乐", "age": 18}

五、方案实战

1、SQL查询方案

##可以通过format参数控制返回结果的格式,txt表示文本格式,看起来更直观点,默认为json格式。
POST _sql?format=txt
{
"query": "SELECT name,age FROM distinct_index group by name,age"
}

查询结果:

elasticsearch中如何实现dinstinct去重功能_elasticsearch


和预期相符,查询结果达到去重的效果。

SQL语句转DSL:

POST /_sql/translate
{
"query": "SELECT name,age FROM distinct_index group by name,age"
}

结果:

{
"size" : 0,
"_source" : false,
"stored_fields" : "_none_",
"aggregations" : {
"groupby" : {
"composite" : {
"size" : 1000,
"sources" : [
{
"f5b401c4" : {
"terms" : {
"field" : "name",
"missing_bucket" : true,
"order" : "asc"
}
}
},
{
"f557e07b" : {
"terms" : {
"field" : "age",
"missing_bucket" : true,
"order" : "asc"
}
}
}
]
}
}
}
}

说明:
通过将sql语句转为dsl语句可以发现,sql语句中的group by查询底层原理是转化成了dsl中的aggregations聚合查询。

2、aggregations聚合查询

POST distinct_index/_search
{
"from": 0,
"size": 0,
"aggregations": {
"name": {
"terms": {
"field": "name",
"size": 2147483647
},
"aggregations": {
"age": {
"terms": {
"field": "age",
"size": 2147483647
}
}
}
}
}
}

查询结果:

{
"took" : 3,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 8,
"relation" : "eq"
},
"max_score" : null,
"hits" : [ ]
},
"aggregations" : {
"name" : {
"doc_count_error_upper_bound" : 0,
"sum_other_doc_count" : 0,
"buckets" : [
{
"key" : "小天",
"doc_count" : 2,
"age" : {
"doc_count_error_upper_bound" : 0,
"sum_other_doc_count" : 0,
"buckets" : [
{
"key" : 25,
"doc_count" : 2
}
]
}
},
{
"key" : "小明",
"doc_count" : 2,
"age" : {
"doc_count_error_upper_bound" : 0,
"sum_other_doc_count" : 0,
"buckets" : [
{
"key" : 15,
"doc_count" : 2
}
]
}
},
{
"key" : "乐乐",
"doc_count" : 1,
"age" : {
"doc_count_error_upper_bound" : 0,
"sum_other_doc_count" : 0,
"buckets" : [
{
"key" : 18,
"doc_count" : 1
}
]
}
},
{
"key" : "小红",
"doc_count" : 1,
"age" : {
"doc_count_error_upper_bound" : 0,
"sum_other_doc_count" : 0,
"buckets" : [
{
"key" : 12,
"doc_count" : 1
}
]
}
},
{
"key" : "老万",
"doc_count" : 1,
"age" : {
"doc_count_error_upper_bound" : 0,
"sum_other_doc_count" : 0,
"buckets" : [
{
"key" : 35,
"doc_count" : 1
}
]
}
},
{
"key" : "老王",
"doc_count" : 1,
"age" : {
"doc_count_error_upper_bound" : 0,
"sum_other_doc_count" : 0,
"buckets" : [
{
"key" : 45,
"doc_count" : 1
}
]
}
}
]
}
}
}

六、异常记录

1、ES中的sql查询不支持DISTINCT关键字

POST _sql?format=txt
{
"query": "SELECT DISTINCT name,age FROM distinct_index"
}

报错:

{
"error" : {
"root_cause" : [
{
"type" : "verification_exception",
"reason" : "Found 1 problem\nline 1:8: SELECT DISTINCT is not yet supported"
}
],
"type" : "verification_exception",
"reason" : "Found 1 problem\nline 1:8: SELECT DISTINCT is not yet supported"
},
"status" : 400
}

2、ES的sql查询中表名中不能有中划线,比如my-index-000001

PUT my-index-000001
{
"mappings": {
"properties": {
"name": {
"type": "keyword"
},
"age": {
"type": "integer"
}
}
}
}

POST _sql?format=txt
{
"query": "SELECT name FROM my-index-000001"
}

报错:

{
"error" : {
"root_cause" : [
{
"type" : "parsing_exception",
"reason" : "line 1:20: extraneous input '-' expecting {<EOF>, ',', 'ANALYZE', 'ANALYZED', 'AS', 'CATALOGS',
……

遇到这种情况,最简单方法是给索引添加别名。

POST /_aliases
{
"actions" : [
{ "add" : { "index" : "my-index-000001", "alias" : "my_index" } }
]
}
POST _sql?format=txt
{
"query": "SELECT name FROM my_index"
}

总结

本文主要介绍了ES中如何实现类似dinstinct的数据去重功能。
1、首先通过通过dinstinct和group by的等价sql语句,说明可以通过分组函数实现数据去重。
2、分别介绍了ES中通过sql语句查询和aggregations聚合查询实现对查询结果的去重。
3、ES中的sql查询不支持DISTINCT关键字
4、ES中的sql查询中表名不能包含中划线,比如my-index-000001


标签:count,index,功能,name,doc,age,elasticsearch,sql,dinstinct
From: https://blog.51cto.com/u_15905482/5919982

相关文章

  • SpringBoot整合elasticsearch-rest-client实战
    前言很多人在Springboot项目中都已经习惯采用Spring家族封装的spring-data-elasticsearch来操作elasticsearch,而官方更推荐采用rest-client。今天给大家介绍下在springbo......
  • 全网最详细elasticsearch7.10.2安装手册
    前言网上关于elasticsearch的安全教程很多,但是只是局限在最基础的启动就成功就完了。今天给大家分享elasticsearch7.10.2最全安装手册,记录自己踩过的一些坑。一、环境说明服......
  • 还不会ES?Elasticsearch快速入门实操指南送上
    前言本文主要介绍ES的常用请求,让大家能快速上手ES的使用主要参考官网的​​Quickstart​​指引。一、请求方式向Elasticsearch发送请求主要有2种方式:1、使用restapi发送h......
  • lightdb vacuum用法--功能与参数
    lightdb没有像Oracle那样的undo来存放旧版本;而是将旧版本直接存放于relation文件中。那么带来的问题就是deadtuple过多,导致relation文件不断增大而带来空间膨胀问题。......
  • elasticsearch安装和使用
    下载地址:https://www.elastic.co/cn/downloads/past-releases#elasticsearch    https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.10.1-......
  • 140-viewerjs图片预览功能
    <linkrel="stylesheet"href="${ctxJs}/viewerjs/viewer.css"> <scriptsrc="${ctxJs}/viewerjs/viewer.js"></script>定义一个div,图片区:<divid="picShow"><img......
  • SOLIDWORKS 2023新功能 SW材料明细表功能升级
    今天微辰三维和大家分享SOLIDWORKS2023工程图的亮点新功能之一:材料明细表的覆盖。材料明细表的覆盖SOLIDWORKS工程图是我们常用的功能之一。当采用断开链接模式修改材料明......
  • yolov3/4 转换为caffemodel 并且验证检测图片功能 简单记录遇到的一个问题
    过程需要设计github上的caffe、darknet2caffe、caffe-yolov3等资源,具体编译安装过程可以参考网络上的其他资源。注意这个过程有一个很关键的地方,就是caffe-yolov3的实现是......
  • FinClip产品更新:FIDE 插件开发功能优化;开发者文档英文版上线
    不知不觉22年进入尾声,通过一年的不断打磨,FinClip也在不断成长,现在,让我们看看过去的11月,FinClip又有了哪些新的变化。产品方面的相关动向......
  • springboot+Elasticsearch 复杂查询
    以前没做过ES里面的查询,第一次接触还是走了点弯路的。就是这个字段你在ES都不用模糊查的话,就可以设置 type=FieldType.Keyword,比如ID之类的。一:建ES存储的实体imp......