带家好,我是马儿,这次来讲一下最近遇到的一个问题

我司某个环境的es中被导入了重复数据,导致查询的时候会出现一些重复数据,所以要我们几个开发想一些解决方案,我们聊了聊,相出了下面一些方案:

1.从源头解决:导入数据时进行唯一性校验

2.从数据解决:清洗数据,将重复的数据查出后清理,然后入库

3.从查询解决:查询时筛选重复数据

我就从查询着手,找到了聚合查询的方法

聚合(Aggregations)

聚合功能为ES带来了统计分析的能力,类似于SQL语言中的group by,avg,sum等函数

桶(Buckets):符合条件的文档的集合,相当于SQL中的group by

桶的概念在很多地方有应用,比如桶排序,HashMap的实现中数组也可看作桶,等等等等

示例:

根据city,对twitter索引的文档进行分组

aggs:聚合

my:自定义名称

terms:根据结果分类

field:筛选字段

city:需要分类的字段

GET /twitter/doc/_search
{
"from": 0,
"size": 0,
"aggs": {
"my":{
"terms":{
"field": "city"
}
}
}
}

结果中聚合的部分:

计算出了类型和命中的数量

"aggregations": {
"my": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": "北京",
"doc_count": 105
},
{
"key": "上海",
"doc_count": 1
}
]
}
}

但这不是只有统计结果吗,我要的是筛选后的数据啊

top_hits指标聚合器

top_hits指标聚合器跟踪要聚合的最相关文档,可以有效地用于通过存储桶聚合器按某些字段对结果集进行分组。

选项:

from-要获取的第一个结果的偏移量。

size-每个存储桶要返回的最匹配匹配项的最大数目。 默认情况下,返回前三个匹配项。

排序-匹配的热门匹配的排序方式。 默认情况下,命中按主要查询的分数排序。

示例:

根据city,对twitter索引的文档进行分组、根据age进行排序、结果只包含user+age+city,然后显示每组的一条数据

aggs:聚合

my:自定义名称

terms:根据结果分类

field:筛选字段

city:需要分类的字段

sort:排序

age:排序依据字段

order:排序方式

desc:降序

_source includes:结果包含的字段

size:每组显示的数量

{
"from": 0,
"size": 0,
"aggs": {
"my":{
"terms":{
"field": "city"
},
"aggs":{
"my_top_hits":{
"top_hits":{
"sort": [
{
"age": {
"order": "desc"
}
}
],
"_source": {
"includes": [
"user",
"age",
"city"
]
},
"size":1
}
}
}
}
}
}

结果中聚合的部分:

"aggregations": {
"my": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": "北京",
"doc_count": 105,
"my_top_hits": {
"hits": {
"total": 105,
"max_score": null,
"hits": [
{
"_index": "twitter",
"_type": "doc",
"_id": "AW5jwgirrweXGTc7-cPA",
"_score": null,
"_source": {
"city": "北京",
"user": "朝阳区-老王",
"age": 50
},
"sort": [
50
]
}
]
}
}
},
{
"key": "上海",
"doc_count": 1,
"my_top_hits": {
"hits": {
"total": 1,
"max_score": null,
"hits": [
{
"_index": "twitter",
"_type": "doc",
"_id": "AW5jwiM1rweXGTc7-cPB",
"_score": null,
"_source": {
"city": "上海",
"user": "虹桥-老吴",
"age": 90
},
"sort": [
90
]
}
]
}
}
}
]
}
}

但是光使用terms,我添加了多个字段后查不出来东西了都,难道这样还不行吗

使用script进行聚合

常规的聚合无法在聚合中进行复杂操作,所以要加入脚本

示例:

修改terms中内容为下,将三个条件拼接起来

"terms":{
"script": "doc['user.keyword'].value + '#' + doc['age'].value + '#' +doc['city'].value"
},

查询结果:

key:拼接的条件

doc_count:每组重复的数目

"aggregations": {
"my": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": "双榆树-张三#20#北京",
"doc_count": 101,
"my_top_hits": {
"hits": {
"total": 101,
"max_score": null,
"hits": [
{
"_index": "twitter",
"_type": "doc",
"_id": "AW9lr8sBP5iHlpen8GYt",
"_score": null,
"_source": {
"city": "北京",
"user": "双榆树-张三",
"age": 20
},
"sort": [
20
]
}
]
}
}
},
{
"key": "东城区-李四#30#北京",
"doc_count": 1,
"my_top_hits": {
"hits": {
"total": 1,
"max_score": null,
"hits": [
{
"_index": "twitter",
"_type": "doc",
"_id": "AW5jwaOIrweXGTc7-cO-",
"_score": null,
"_source": {
"city": "北京",
"user": "东城区-李四",
"age": 30
},
"sort": [
30
]
}
]
}
}
},
{
"key": "东城区-老刘#30#北京",
"doc_count": 1,
"my_top_hits": {
"hits": {
"total": 1,
"max_score": null,
"hits": [
{
"_index": "twitter",
"_type": "doc",
"_id": "AW5jwXhcrweXGTc7-cO9",
"_score": null,
"_source": {
"city": "北京",
"user": "东城区-老刘",
"age": 30
},
"sort": [
30
]
}
]
}
}
},
{
"key": "朝阳区-老王#50#北京",
"doc_count": 1,
"my_top_hits": {
"hits": {
"total": 1,
"max_score": null,
"hits": [
{
"_index": "twitter",
"_type": "doc",
"_id": "AW5jwgirrweXGTc7-cPA",
"_score": null,
"_source": {
"city": "北京",
"user": "朝阳区-老王",
"age": 50
},
"sort": [
50
]
}
]
}
}
},
{
"key": "朝阳区-老贾#35#北京",
"doc_count": 1,
"my_top_hits": {
"hits": {
"total": 1,
"max_score": null,
"hits": [
{
"_index": "twitter",
"_type": "doc",
"_id": "AW5jwcvBrweXGTc7-cO_",
"_score": null,
"_source": {
"city": "北京",
"user": "朝阳区-老贾",
"age": 35
},
"sort": [
35
]
}
]
}
}
},
{
"key": "虹桥-老吴#90#上海",
"doc_count": 1,
"my_top_hits": {
"hits": {
"total": 1,
"max_score": null,
"hits": [
{
"_index": "twitter",
"_type": "doc",
"_id": "AW5jwiM1rweXGTc7-cPB",
"_score": null,
"_source": {
"city": "上海",
"user": "虹桥-老吴",
"age": 90
},
"sort": [
90
]
}
]
}
}
}
]
}
}

可以看到,每组都不一样,我们script真是太强大了

Java实现



使用elasticsearch包中的工具类,将索引中所有字段进行拼接,作为aggregation参数传入查询即可

总结:

本文介绍了es的聚合功能,aggs+top_hits+script就能过滤重复数据,得到唯一结果。

但是这边也有个坑,es聚合本身不支持分页

这个分页以后有机会再说

Elasticsearch去重查询/过滤重复数据(聚合)的更多相关文章

  1. 手把手教你如何用java8新特性将List中按指定属性排序,过滤重复数据

    在java中常常会遇到这样一个问题,在实际应用中,总会碰到对List排序并过滤重复的问题,如果List中放的只是简单的String类型过滤so easy,但是实际应用中并不会这么easy,往往List ...

  2. scrapy过滤重复数据和增量爬取

    原文链接 前言 这篇笔记基于上上篇笔记的---<scrapy电影天堂实战(二)创建爬虫项目>,而这篇又涉及redis,所以又先熟悉了下redis,记录了下<redis基础笔记> ...

  3. sql 查询重复数据,删除重复数据,过滤重复数据

    select * from (SELECT titleid,count(titleid) c FROM [DragonGuoShi].[dbo].[ArticleInfo] group by titl ...

  4. Oracle查询和过滤重复数据

    对数据库某些意外情况,引起的重复数据,如何处理呢? ----------------查重复: select * from satisfaction_survey s and s.project_no ...

  5. MySQL 数据库查询数据,过滤重复数据保留一条数据---(MySQL中的row_number变相实现方法)

    转自: http://www.maomao365.com/?p=10564 摘要: 下文讲述MySQL数据库查询重复数据时,只保留一条数据的方法 实现思路: 在MySQL数据库中没有row_numbe ...

  6. SQL查询去掉重复数据

    本文主要总结数据库去掉重复数据的方法 去掉重复数据的方法: 第一种:distinct 根据单个字段去重,能精确去重: 作用在多个字段时,只有当这几个字段的完全相同时,才能去重: 关键字distinct ...

  7. 爬虫数据使用MongDB保存时自动过滤重复数据

    本文转载自以下网站: 爬虫断了?一招搞定 MongoDB 重复数据 https://www.makcyun.top/web_scraping_withpython13.html 需要学习的地方: Mo ...

  8. sql查询删除重复数据

    数据库UserInfo 删除重复数据 即删除重复的用户名手机号 同一个用户名手机号只保留一个用户 01.根据多个字段查询重复数据 with data1 as( select MobilePhone,N ...

  9. mysql语句删除重复数据,保留一条;查询所有重复数据;查询重复数据的一条,

    //显示重复的所有条 SELECT * FROM 表名 WHERE (字段1,字段2,...) IN (SELECT 字段1,字段2,...FROM 表名 GROUP BY 字段1,字段2,... H ...

随机推荐

  1. HashMap集合嵌套集合方法四种

    Map<String, HashMap<Person, String>> m=new HashMap<String, HashMap<Person, String& ...

  2. spring——bean自动装配

    注意:自动装配功能和手动装配要是同时使用,那么自动装配就不起作用. beans.xml <?xml version="1.0" encoding="UTF-8&qu ...

  3. RocketMQ安装及入门

    本文是作者原创,版权归作者所有.若要转载,请注明出处. 本文RocketMQ版本为rocketmq-all-4.7.0,系统为win10.请各位去官网下载,也可以留言,我发安装包 RocketMQ安装 ...

  4. ## H5 canvas画图白板踩坑

    最近接手了一个小型的H5,最主要的功能大概就是拍照上传和canvas画板了. 主要是记录一下自己菜到像傻子一样的技术. 1.canvas画板隔空打牛!画布越往上部分错位距离越小,越往下距离越大. 2. ...

  5. Spring boot Sample 002之spring-boot-banner

    一.环境 1.1.Idea 2020.1 1.2.JDK 1.8 二.目的 学习Spring Boot Banner自定义的操作   三.步骤 3.1.点击File -> New Project ...

  6. Java工作流框架jflow 集团应用模式用户组功能

    关键字 驰骋BPM ,工作流开发框架,用户组,接受人规则,用户组发起人范围,选择人范围. 集团工作模式. Ccflow ,jflow.工作流引擎 名词定义与应用背景 对于集团模式的ccflow,jfl ...

  7. JavaScript 引用数据类型

    目录 1. 问题描述 2. 原因分析 3. React 中的引用数据类型 4. 业务场景 5. 参考资料 1. 问题描述 今天在写一个代码题时候, 有一个BUG 导致自己停滞好久, 该BUG 可以描述 ...

  8. JavaSE(三) 变量与运算符

    个人博客网:https://wushaopei.github.io/    (你想要这里多有) 2 变量的使用 2.1按数据类型分类 ​ 整型 : byte(1字节 = 8bit) short(2字节 ...

  9. 数据库之 MySQL --- 下载、安装 及 概述(一)

    个人博客网:https://wushaopei.github.io/    (你想要这里多有) 一 . MySql数据库的安装 1.图解MySQL程序结构 ​ 2.双击运行安装程序:以Win32位为例 ...

  10. 进程调度函数scheduler_tick()的触发原理:周期PERIODIC定时器

    参考文章: https://www.jb51.net/article/133579.htm https://blog.csdn.net/flaoter/article/details/77509553 ...