2014-04-18 5 views
5

Ich habe eine ElasticSearch-Abfrage, die Abfragen über einen Index und dann aggregiert basierend auf einem bestimmten Feld sender_not_analyzed. Ich benutze dann eine Begriff Aggregation auf das gleiche Feld sender_not_analyzed, die Eimer für die oberen "Absender" zurückgibt. Meine Frage ist jetzt:ElasticSearch Query durch eindeutige Teilzeichenfolgen (E-Mail-Domäne)

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

die Eimer zurück, die wie folgt aussehen:

"aggregations": { 
     "sender-stats": { 
     "buckets": [ 
      { 
       "key": "<Mike <[email protected]>@MISSING_DOMAIN>", 
       "doc_count": 5017 
      }, 
      { 
       "key": "[email protected]", 
       "doc_count": 3963 
      }, 
      { 
       "key": "[email protected]", 
       "doc_count": 2857 
      }, 
      { 
       "key": "[email protected]", 
       "doc_count":1544 
      } 

Wie kann ich eine Aggregation schreiben, so dass ich einzelne Eimer für jede einzelne E-Mail-Domain erhalten, zB foo.com hätte eine doc_count von (3963 + 2857) 6820? Kann ich dies mit einer Regex-Aggregation erreichen oder muss ich einen benutzerdefinierten Analysator schreiben, um die Zeichenfolge am @ bis zum Ende der Zeichenfolge zu trennen?

Antwort

3

Das ist ziemlich spät, aber ich denke, dies durch den Einsatz pattern_replace char filter getan werden kann, können Sie die Domain-Namen mit regex erfassen, Dies ist mein Setup

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

Hier domain char filter wird den Domain-Namen zu erfassen, müssen wir Verwenden Sie keyword tokenizer, um die Domain zu erhalten, wie es ist, verwende ich lowercase Filter, aber es liegt an Ihnen, ob Sie es verwenden möchten oder nicht. Mit dem Parameter copy_to kopieren Sie den Wert des Feldes sender_not_analyzed in das Feld domain, obwohl das Feld _source nicht geändert wird, um diesen Wert einzuschließen, aber wir können es abfragen.

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

Dies wird Ihnen das gewünschte Ergebnis geben.