其他
fingerprint filter 插件——Elasticsearch 去重必备利器
1、实战问题
问题1:es 中 scroll 游标不能与 collapse 共用,有什么办法可以实现 collapse 的效果? 问题2:采集互联网数据有重复数据写入 Elasticsearch,如何去重后放到另外索引?
2、排查思路
2.1 Elasticsearch 去重的几种方式
方式一:terms 指定字段聚合 + top_hits 子聚合。 方式二:collapse 折叠去重。
{"index":{"_id":1}}
{"title":"南开录取通知书亮相,附赠嘉兴莲花种子、一封特殊的信","cont":"今天,南开大学晒出建党百年特别版录取通知书。","url":"https://baijiahao.baidu.com/s?id=1703334751082094750&wfr=spider&for=pc","publish_time":"2021-06-23 13:36"}
{"index":{"_id":2}}
{"title":"南开录取通知书亮相,附赠嘉兴莲花种子、一封特殊的信","cont":"今天,南开大学晒出建党百年特别版录取通知书。","url":"https://baijiahao.baidu.com/s?id=1703334751082094750&wfr=spider&for=pc","publish_time":"2021-06-23 13:36"}
{"index":{"_id":3}}
{"title":"南开录取通知书亮相,附赠嘉兴莲花种子、一封特殊的信","cont":"今天,南开大学晒出建党百年特别版录取通知书。","url":"https://baijiahao.baidu.com/s?id=1703334751082094750&wfr=spider&for=pc","publish_time":"2021-06-23 13:36"}
{"index":{"_id":4}}
{"title":"建党百年特别版!南开大学录取通知书送两粒嘉兴莲花种子","cont":"@南开大学 6月23日消息,建党百年特别版南开大学录取通知书揭秘!","url":"https://www.163.com/dy/article/GD69KNIR0514R9P4.html","publish_time":"2021-06-23 13:25:00"}
# top_hits 子聚合去重
GET news/_search
{
"query": {
"match_all": {}
},
"aggs": {
"type": {
"terms": {
"field": "title.keyword",
"size": 10
},
"aggs": {
"title_top": {
"top_hits": {
"_source": {
"includes": [
"title"
]
},
"sort": [
{
"title.keyword": {
"order": "desc"
}
}
],
"size": 1
}
}
}
}
},
"size": 0
}
# collapse 去重
GET news/_search
{
"query": {
"match_all": {}
},
"collapse": {
"field": "title.keyword"
}
}
2.2 Elasticsearch scroll 不支持 collapse 确认
2.3 考虑新方案
数据源:爬虫采集互联网数据(由于是采集数据,难免会有转载等重复数据)。 源数据存储:Mysql。 如何界定重复?基于:发文标题、发文时间、发文正文内容、发文url 组成字段的MD5值作为去重标记。
3、logstash fingerprint filter 插件介绍
3.1 fingerprint filter 插件版本
3.2 fingerprint filter 插件用途
4、logstash fingerprint filter 去重实战
4.1 同步脚本
# Read all documents from Elasticsearch
elasticsearch {
hosts => "172.21.0.14:19022"
index => "news"
query => '{ "sort": [ "_doc" ] }'
}
}
filter {
fingerprint {
key => "1234ABCD"
method => "SHA256"
source => ["title", "cont", "url", "publish_time"]
target => "[@metadata][generated_id]"
concatenate_sources => true
}
}
output {
stdout { codec => dots }
elasticsearch {
hosts => "172.21.0.14:19022"
index => "news_after_fingerprint"
document_id => "%{[@metadata][generated_id]}"
}
}
4.1.1 脚本讲解
第一:input,代表输入(读取端),本实例自然是基于 Elasticsearch 读。 第二:filter,代表中间处理,那就是指纹处理部分。 第三:output,代表输出(写入端),本实例还是写入 Elasticsearch,只不过会写入新的索引 news_after_fingerprint。
4.1.2 filter 环节核心参数讲解
key => "1234ABCD",代表当前指纹的唯一值。 method => "SHA256",指纹生成方式。 source => ["title", "cont", "url", "publish_time"],生成指纹的基础字段名称。 target => "[@metadata][generated_id]":将存储生成的指纹的字段的名称,后面output 环节会使用。该字段的任何当前内容都将被覆盖。 concatenate_sources => true
4.2 同步实操
4.3 成功标记
5、小结
问题1 答案:不用 collapse,用 fingerprint filter 插件将数据转存为另外索引,然后 scroll 遍历输出就可以。 问题2 答案:用 fingerprint filter 插件将数据转存为另外索引即可。
能将去重后的数据独立存储为一个索引,且无需额外操作。 方便业务单独处理数据。