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

我司某个环境的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. 玩转Nginx location配置

    原文链接:https://mp.weixin.qq.com/s/kaEtfmX9bVdKfCVY6gbOsQ 建议点击原文链接查看 nginx是一个跨平台的web服务器, 基于事件驱动的架构并发处理百 ...

  2. Android设置按钮透明

    <Button android:id="@+id/bt3" android:layout_width="163dp" android:layout_hei ...

  3. 替换Java WEB工程文件的指定字符串

    package com.utils; import java.io.BufferedReader;import java.io.File;import java.io.FileFilter;impor ...

  4. 货车运输 noip2013 luogu P1967 (最大生成树+倍增LCA)

    luogu题目传送门! 首先,题目让我们求每个货车的最大运输量,翻译一下就是求路径上边权最小的边. 利用一下贪心思想可知,所有货车肯定都会尽量往大的边走. 进一步翻译,即为有一些小边货车根本不会走,或 ...

  5. Pycharm虚拟环境的使用

    Pycharm虚拟环境的使用 pycharm创建项目的时候,一定勾选inhert global site-packages.不然系统的库就没法用了. 打开Project Interpreters页面: ...

  6. C/C++多参数函数参数的计算顺序与压栈顺序

    一.前言 今天在看Thinking in C++这本书时,书中的一个例子引起了我的注意,具体是使用了下面这句 单看这条语句的语义会发现仅仅是使用一个简单的string的substr函数将所得子串pus ...

  7. PowerPC-MPC56xx Flash模式代码启动过程

    https://mp.weixin.qq.com/s/iruM5VwKgnH_7nmIQxO0-g   参考第5章   In order for the e200z4d core to be able ...

  8. Chisel3 - bind - Data

    https://mp.weixin.qq.com/s/ENJVkz88sGgyODRNCu9jhQ   介绍Data类中的binding的定义和用法.   Binding stores informa ...

  9. 使用turtle库绘制一个叠加等边三角形

    import turtle as t t.setup(600, 600, None,None) t.pu() t.fd(-120) t.pensize(5) t.width(5) t.pencolor ...

  10. Java实现 蓝桥杯 算法提高 p1001

    算法提高 P1001 时间限制:1.0s 内存限制:256.0MB 提交此题  当两个比较大的整数相乘时,可能会出现数据溢出的情形.为避免溢出,可以采用字符串的方法来实现两个大数之间的乘法.具体来说 ...