2016-08-01 65 views

回答

1

你需要一个pattern_capture filter,应该只能捕获@后面的内容。此外,不要与文本的原始分析一塌糊涂,我建议增加一个子场到原来的email场,并与工作只针对这一特定聚集:

PUT /test 
{ 
    "settings": { 
    "analysis": { 
     "filter": { 
     "email_domains": { 
      "type": "pattern_capture", 
      "preserve_original" : 0, 
      "patterns": [ 
      "@(.+)" 
      ] 
     } 
     }, 
     "analyzer": { 
     "email": { 
      "tokenizer": "uax_url_email", 
      "filter": [ 
      "email_domains", 
      "lowercase", 
      "unique" 
      ] 
     } 
     } 
    } 
    }, 
    "mappings": { 
    "emails": { 
     "properties": { 
     "email": { 
      "type": "string", 
      "fields": { 
      "domain": { 
       "type": "string", 
       "analyzer": "email" 
      } 
      } 
     } 
     } 
    } 
    } 
} 

尝试一些测试数据:

POST /test/emails/_bulk 
{"index":{"_id":"1"}} 
{"email": "[email protected]"} 
{"index":{"_id":"2"}} 
{"email": "[email protected], [email protected]"} 
{"index":{"_id":"3"}} 
{"email": "[email protected]"} 
{"index":{"_id":"4"}} 
{"email": "[email protected]"} 
{"index":{"_id":"5"}} 
{"email": "[email protected]"} 

并为您的具体使用情况下,类似下面的简单聚合应该这样做:

GET /test/emails/_search 
{ 
    "size": 0, 
    "aggs": { 
    "by_domain": { 
     "terms": { 
     "field": "email.domain", 
     "size": 10 
     } 
    } 
    } 
} 

,结果是这样的:

"aggregations": { 
     "by_domain": { 
     "doc_count_error_upper_bound": 0, 
     "sum_other_doc_count": 0, 
     "buckets": [ 
      { 
       "key": "outlook.com", 
       "doc_count": 3 
      }, 
      { 
       "key": "gmail.com", 
       "doc_count": 2 
      }, 
      { 
       "key": "yahoo.com", 
       "doc_count": 1 
      } 
     ] 
     } 
    }