Elasticsearch去重查询/过滤重复数据(聚合)
带家好,我是马儿,这次来讲一下最近遇到的一个问题
我司某个环境的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去重查询/过滤重复数据(聚合)的更多相关文章
- 手把手教你如何用java8新特性将List中按指定属性排序,过滤重复数据
在java中常常会遇到这样一个问题,在实际应用中,总会碰到对List排序并过滤重复的问题,如果List中放的只是简单的String类型过滤so easy,但是实际应用中并不会这么easy,往往List ...
- scrapy过滤重复数据和增量爬取
原文链接 前言 这篇笔记基于上上篇笔记的---<scrapy电影天堂实战(二)创建爬虫项目>,而这篇又涉及redis,所以又先熟悉了下redis,记录了下<redis基础笔记> ...
- sql 查询重复数据,删除重复数据,过滤重复数据
select * from (SELECT titleid,count(titleid) c FROM [DragonGuoShi].[dbo].[ArticleInfo] group by titl ...
- Oracle查询和过滤重复数据
对数据库某些意外情况,引起的重复数据,如何处理呢? ----------------查重复: select * from satisfaction_survey s and s.project_no ...
- MySQL 数据库查询数据,过滤重复数据保留一条数据---(MySQL中的row_number变相实现方法)
转自: http://www.maomao365.com/?p=10564 摘要: 下文讲述MySQL数据库查询重复数据时,只保留一条数据的方法 实现思路: 在MySQL数据库中没有row_numbe ...
- SQL查询去掉重复数据
本文主要总结数据库去掉重复数据的方法 去掉重复数据的方法: 第一种:distinct 根据单个字段去重,能精确去重: 作用在多个字段时,只有当这几个字段的完全相同时,才能去重: 关键字distinct ...
- 爬虫数据使用MongDB保存时自动过滤重复数据
本文转载自以下网站: 爬虫断了?一招搞定 MongoDB 重复数据 https://www.makcyun.top/web_scraping_withpython13.html 需要学习的地方: Mo ...
- sql查询删除重复数据
数据库UserInfo 删除重复数据 即删除重复的用户名手机号 同一个用户名手机号只保留一个用户 01.根据多个字段查询重复数据 with data1 as( select MobilePhone,N ...
- mysql语句删除重复数据,保留一条;查询所有重复数据;查询重复数据的一条,
//显示重复的所有条 SELECT * FROM 表名 WHERE (字段1,字段2,...) IN (SELECT 字段1,字段2,...FROM 表名 GROUP BY 字段1,字段2,... H ...
随机推荐
- 多线程(thread+queue 售票)
一.理解 如果线程里每从队列里取一次,但没有执行task_done(),则join无法判断队列到底有没有结束,在最后执行个join()是等不到结果的,会一直挂起.可以理解为,每task_done一次 ...
- 杂谈WebApiClient的性能优化
前言 WebApiClient的netcoreapp版本的开发已接近尾声,最后的进攻方向是性能的压榨,我把我所做性能优化的过程介绍给大家,大家可以依葫芦画瓢,应用到自己的实际项目中,提高程序的性能. ...
- JVM调优总结(五)-典型配置举例
以下配置主要针对分代垃圾回收算法而言. 堆大小设置 年轻代的设置很关键 JVM中最大堆大小有三方面限制:相关操作系统的数据模型(32-bt还是64-bit)限制:系统的可用虚拟内存限制:系统的可用物理 ...
- sqlmap基本使用
sqlmap 使用 需要安装python2的环境 使用方法: 用最基础的get型注入开始 1.当我们发现注入点的时候, python sqlmap.py -u "http://192.168 ...
- PreparedStatement实现针对不同表的通用查询操作
PreparedStatement实现针对不同表的通用查询操作:查询一样和多行 PreparedStatementQueryTest package com.aff.PreparedStatement ...
- Android 中加载本地Html 跨域问题,http协议允许加载
一.需求: 后台加载HTML的包时间太长,太卡,让把所有的HTML包放到前台:使用的是file://协议,有些内容和样式加载不出来,H5那边说需要用http://协议来加载: 二.处理过程: 安卓最简 ...
- IT笑话十则(二)
一.女程序员征婚 女程序员是这么征婚的: SELECT * FROM 男人们 WHERE 未婚=true and 同性恋=false and 有房=true and 有车=true and 条件 in ...
- Rocket - util - ReduceOthers
https://mp.weixin.qq.com/s/gbR5fuDbE_nUFVxw-p4rsA 简单介绍ReduceOthers的实现. 1. 基本介绍 输入一组Bool元素 ...
- 在jsp文件中出现Unknown tag (c:out)
出现这个提示之后,这个out是没有被执行的,在最前面加上 <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix= ...
- Java实现 蓝桥杯VIP 算法提高 3-2求存款
算法提高 3-2求存款 时间限制:1.0s 内存限制:256.0MB 问题描述 见计算机程序设计基础(乔林)P50第5题. 接受两个数,一个是用户一年期定期存款金额,一个是按照百分比格式表示的利率,计 ...