elasticsearch 聚合哈希的唯一条目并找到所有标签
elasticsearch aggregate unique entries of hashes and find all tags
我在单个索引中有两组散列,使用不同的标签作为附加字段,如下所示:
索引:哈希-*
sha1-c tag
abcdefg12345 collect
abcdefg12345 collect
bcdefgh12345 collect
cdefghi collect
sha1-m tag
abclefg bad
abcgefg bad
cdefghi bad
如何找到索引中两个标签之间的所有重复项?我更喜欢 kibana 中的数据表或可视化,但 elasticsearch aggregation/query 就足够了。
格式
t _index sha1-c
t _type sha1-c
t sha1-c cdefghi
t tag sha1-c
t _index sha1-m
t _type sha1-m
t sha1-m cdefghi
t tag sha1-m
预期结束状态:
hash_matches
cdefghi
首先,您的两个索引具有相同的字段名称很重要。此外,为简单起见,tag
和 sha-1c
字段应该有一个子字段(或它们自己)应该是 keyword
s 以便 terms
聚合不会错误地触发分析文本。
这是我的建议(用 5.3 测试过)。在 2.x 中,可能需要稍微更改脚本。在 1.x 中,此解决方案将不起作用,因为那里没有可用的管道聚合。
解决方案基本上是在 sha 值上创建一个 terms
聚合,然后为每个 sha 计算它找到的不同标签。如果这些标签计数高于两个,则存在具有其中两个的 sha。现在,如果我们知道 如果每个 sha 值在每个索引 中只找到一次,那将是一个更可靠的解决方案。是这样的吗?如果是这样,下面 tag
字段上的聚合应转换为 _index
字段上的聚合。
DELETE sha1-*
PUT sha1-c
{
"mappings": {
"sha1-c": {
"properties": {
"sha1-c": {
"type": "keyword"
},
"tag": {
"type": "keyword"
}
}
}
}
}
PUT sha1-m
{
"mappings": {
"sha1-m": {
"properties": {
"sha1-c": {
"type": "keyword"
},
"tag": {
"type": "keyword"
}
}
}
}
}
POST /sha1-c/sha1-c/_bulk
{"index":{}}
{"sha1-c":"abcdefg12345","tag":"collect"}
{"index":{}}
{"sha1-c":"abcdefg12345","tag":"collect"}
{"index":{}}
{"sha1-c":"bcdefgh12345","tag":"collect"}
{"index":{}}
{"sha1-c":"cdefghi","tag":"collect"}
POST /sha1-m/sha1-m/_bulk
{"index":{}}
{"sha1-c":"abclefg","tag":"bad"}
{"index":{}}
{"sha1-c":"abcgefg","tag":"bad"}
{"index":{}}
{"sha1-c":"cdefghi","tag":"bad"}
GET /sha1-*/_search
{
"size": 0,
"aggs": {
"myField": {
"terms": {
"field": "sha1-c"
},
"aggs": {
"count_tags": {
"cardinality": {
"field": "tag"
}
},
"values_bucket_filter_by_tags_count": {
"bucket_selector": {
"buckets_path": {
"count": "count_tags"
},
"script": "params.count >= 2"
}
}
}
}
}
}
我在单个索引中有两组散列,使用不同的标签作为附加字段,如下所示:
索引:哈希-*
sha1-c tag
abcdefg12345 collect
abcdefg12345 collect
bcdefgh12345 collect
cdefghi collect
sha1-m tag
abclefg bad
abcgefg bad
cdefghi bad
如何找到索引中两个标签之间的所有重复项?我更喜欢 kibana 中的数据表或可视化,但 elasticsearch aggregation/query 就足够了。
格式
t _index sha1-c
t _type sha1-c
t sha1-c cdefghi
t tag sha1-c
t _index sha1-m
t _type sha1-m
t sha1-m cdefghi
t tag sha1-m
预期结束状态:
hash_matches
cdefghi
首先,您的两个索引具有相同的字段名称很重要。此外,为简单起见,tag
和 sha-1c
字段应该有一个子字段(或它们自己)应该是 keyword
s 以便 terms
聚合不会错误地触发分析文本。
这是我的建议(用 5.3 测试过)。在 2.x 中,可能需要稍微更改脚本。在 1.x 中,此解决方案将不起作用,因为那里没有可用的管道聚合。
解决方案基本上是在 sha 值上创建一个 terms
聚合,然后为每个 sha 计算它找到的不同标签。如果这些标签计数高于两个,则存在具有其中两个的 sha。现在,如果我们知道 如果每个 sha 值在每个索引 中只找到一次,那将是一个更可靠的解决方案。是这样的吗?如果是这样,下面 tag
字段上的聚合应转换为 _index
字段上的聚合。
DELETE sha1-*
PUT sha1-c
{
"mappings": {
"sha1-c": {
"properties": {
"sha1-c": {
"type": "keyword"
},
"tag": {
"type": "keyword"
}
}
}
}
}
PUT sha1-m
{
"mappings": {
"sha1-m": {
"properties": {
"sha1-c": {
"type": "keyword"
},
"tag": {
"type": "keyword"
}
}
}
}
}
POST /sha1-c/sha1-c/_bulk
{"index":{}}
{"sha1-c":"abcdefg12345","tag":"collect"}
{"index":{}}
{"sha1-c":"abcdefg12345","tag":"collect"}
{"index":{}}
{"sha1-c":"bcdefgh12345","tag":"collect"}
{"index":{}}
{"sha1-c":"cdefghi","tag":"collect"}
POST /sha1-m/sha1-m/_bulk
{"index":{}}
{"sha1-c":"abclefg","tag":"bad"}
{"index":{}}
{"sha1-c":"abcgefg","tag":"bad"}
{"index":{}}
{"sha1-c":"cdefghi","tag":"bad"}
GET /sha1-*/_search
{
"size": 0,
"aggs": {
"myField": {
"terms": {
"field": "sha1-c"
},
"aggs": {
"count_tags": {
"cardinality": {
"field": "tag"
}
},
"values_bucket_filter_by_tags_count": {
"bucket_selector": {
"buckets_path": {
"count": "count_tags"
},
"script": "params.count >= 2"
}
}
}
}
}
}