【问题标题】:Elasticsearch Query aggregated by unique substrings (email domain)由唯一子字符串聚合的 Elasticsearch 查询(电子邮件域)
【发布时间】:2014-06-03 03:10:21
【问题描述】:

我有一个 elasticsearch 查询,它查询索引,然后根据特定字段 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 将有一个 (3963 + 2857) 6820 的 doc_count?我可以使用正则表达式聚合来完成此操作,还是需要编写某种自定义分析器来将 @ 处的字符串拆分到字符串的末尾?

【问题讨论】:

    标签: elasticsearch aggregation


    【解决方案1】:

    这已经很晚了,但我认为这可以通过使用pattern_replace char filter 来完成,你用regex 捕获域名,这是我的设置

    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"
            }
          }
        }
      }
    }
    

    这里domain char filter将捕获域名,我们需要使用keyword tokenizer来获取域名,我正在使用lowercase过滤,但是否使用它取决于你。使用copy_to参数将sender_not_analyzed的值复制到domain字段,虽然_source字段不会被修改包含这个值但我们可以查询。

    GET email_index/_search
    {
      "size": 0,
      "query": {
        "regexp": {
          "sender_not_analyzed": ".*[@].*"
        }
      },
      "aggs": {
        "sender-stats": {
          "terms": {
            "field": "domain"
          }
        }
      }
    }
    

    这会给你想要的结果。

    【讨论】:

      猜你喜欢
      • 2014-11-06
      • 2011-01-27
      • 1970-01-01
      • 2018-10-01
      • 1970-01-01
      • 2016-10-27
      • 1970-01-01
      • 1970-01-01
      • 2014-06-01
      相关资源
      最近更新 更多