我有一个弹性搜索查询,它通过索引查询,然后根据特定字段sender_not_analyzed进行聚合.然后,我在同一字段sender_not_analyzed上使用术语聚合,返回顶部“发件人”的存储桶.我的查询目前是:
{ "size": 0, "query": { "regexp": { "sender_not_analyzed": ".*[@].*" } }, "aggs": { "sender-stats": { "terms": { "field": "sender_not_analyzed" } } } }
返回看起来像这样的桶:
"aggregations": { "sender-stats": { "buckets": [ { "key": "<Mike <mike@fizzbuzz.com>@MISSING_DOMAIN>", "doc_count": 5017 }, { "key": "jon.doe@foo.com", "doc_count": 3963 }, { "key": "jane.doe@foo.com", "doc_count": 2857 }, { "key": "jon.doe@bar.com", "doc_count":1544 }
如何编写聚合,以便为每个唯一的电子邮件域获取单个存储桶,例如foo.com的doc_count为(3963 2857)6820?我可以使用正则表达式聚合来完成此操作,还是需要编写某种自定义分析器来将@中的字符串拆分为字符串的末尾?
这已经很晚了,但我认为这可以通过使用 pattern_replace char filter来完成,你用正则表达式捕获域名,这是我的设置POST email_index { "settings": { "analysis": { "analyzer": { "my_custom_analyzer": { "char_filter": [ "domain" ], "tokenizer": "keyword", "filter": [ "lowercase", "asciifolding" ] } }, "char_filter": { "domain": { "type": "pattern_replace", "pattern": ".*@(.*)", "replacement": "$1" } } } }, "mappings": { "your_type": { "properties": { "domain": { "type": "string", "analyzer": "my_custom_analyzer" }, "sender_not_analyzed": { "type": "string", "index": "not_analyzed", "copy_to": "domain" } } } } }
这里域名char过滤器将捕获域名,我们需要使用keyword tokenizer来获取域名,我使用的是小写过滤器,但是如果你想使用或不使用它取决于你.使用copy_to参数将sender_not_analyzed的值复制到域字段,虽然_source字段不会被修改为包含此值但我们可以查询它.
GET email_index/_search { "size": 0, "query": { "regexp": { "sender_not_analyzed": ".*[@].*" } }, "aggs": { "sender-stats": { "terms": { "field": "domain" } } } }
这将给你想要的结果.