2016-07-07 25 views
0

私はメールで連絡先を検索する必要があります。 ES documentationによれば、これを達成する最も良い方法はuax_url_emailトークナイザを使用することです。ElasticSearch完全一致のメールを検索

settings: { 
    index: { 
    creation_date: "1467895098804", 
    analysis: { 
     analyzer: { 
     email: { 
      type: "custom", 
      tokenizer: "uax_url_email" 
     } 
     } 
    }, 
    number_of_shards: "5", 
    number_of_replicas: "1", 
    uuid: "wL0P6OIaQqqYpFDvIHArTw", 
    version: { 
     created: "2030399" 
    } 
    } 
} 

とマッピング:

contact: { 
    dynamic: "false", 
    properties: { 
    contact_status: { 
     type: "string" 
    }, 
    created_at: { 
     type: "date", 
     format: "strict_date_optional_time||epoch_millis" 
    }, 
    email: { 
     type: "string" 
    }, 
    id: { 
     type: "long" 
    }, 
    mailing_ids: { 
     type: "long" 
    }, 
    subscription_status: { 
     type: "string" 
    }, 
    type_ids: { 
     type: "long" 
    }, 
    updated_at: { 
     type: "date", 
     format: "strict_date_optional_time||epoch_millis" 
    }, 
    user_id: { 
     type: "long" 
    } 
    } 
} 

インデックスを作成した後、私は二つの文書に挿入しました:ここに私のインデックスの設定である

curl -X PUT 'localhost:9200/contacts/contact/2' -d '{"contact_status": "confirmed", "email": "[email protected]", "id": "2", "user_id": "2", "subscription_status": "on"}' 

その後

curl -X PUT 'localhost:9200/contacts/contact/1' -d '{"contact_status": "confirmed", "email": "[email protected]", "id": "1", "user_id": "1", "subscription_status": "on"}' 

とをIメールで連絡先を検索しようとしていますさまざまな方法で:

curl -X POST 'localhost:9200/contacts/_search?pretty' -d '{"query": {"bool": {"must": [ {"match": {"_all": { "query": "[email protected]", "analyzer": "email" } } } ] } } }' 

私は、ID = 1の1件の結果を得るために期待されるが、空のヒットを得た:

{ 
    "took" : 1, 
    "timed_out" : false, 
    "_shards" : { 
    "total" : 5, 
    "successful" : 5, 
    "failed" : 0 
    }, 
    "hits" : { 
    "total" : 0, 
    "max_score" : null, 
    "hits" : [ ] 
    } 
} 

私がテストした次の検索クエリがあった。

curl -X POST 'localhost:9200/contacts/_search?pretty' -d '{"query": {"bool": {"must": [ {"match": {"_all": { "query": "[email protected]", "analyzer": "email" } } } ] } } }' 

2件の結果が返されました:

{ 
    "took" : 2, 
    "timed_out" : false, 
    "_shards" : { 
    "total" : 5, 
    "successful" : 5, 
    "failed" : 0 
    }, 
    "hits" : { 
    "total" : 2, 
    "max_score" : 0.016878016, 
    "hits" : [ { 
     "_index" : "contacts", 
     "_type" : "contact", 
     "_id" : "2", 
     "_score" : 0.016878016, 
     "_source" : { 
     "contact_status" : "confirmed", 
     "email" : "[email protected]", 
     "id" : "2", 
     "user_id" : "2", 
     "subscription_status" : "on" 
     } 
    }, { 
     "_index" : "contacts", 
     "_type" : "contact", 
     "_id" : "1", 
     "_score" : 0.016878016, 
     "_source" : { 
     "contact_status" : "confirmed", 
     "email" : "[email protected]", 
     "id" : "1", 
     "user_id" : "1", 
     "subscription_status" : "on" 
     } 
    } ] 
    } 
} 

あなたが理解しているように、私は検索結果に1文書を得ることを期待していました。私は間違って何をしていますか?

+0

「email」にメールアドレスのみが含まれている場合、そのフィールドを「not_analyzed」としてから、「term」フィルタを使用してメールアドレスを検索してください。 –

+0

私はuser_id、id、および他のフィールドでも検索する必要があるためです。以上のように、私は電子メールの一部で検索したいと思っています。入力に 'example'と入力し、私の場合は両方の文書で 'example'を含む電子メールのリストを取得します。または、「gmail.com」=> id 1の文書を取得する場合 – Hroft

+0

私はこの方法を提案しています:http://stackoverflow.com/questions/30115867/elasticsearch-analyzer-and-tokenizer-for-emailsそれ以外のユースケースを私に教えてください。 –

答えて

1

これは何が起こったかである:

uax_url_email」トークナイザは「標準」トークナイザ(それは切り取っ意味 『に等しい@』)それがない場合には"<text>@<text>.<text>"のパターンを取得する場合を除き、 「@」を切るが、1つのトークンとして全体メールアドレスを取る

は今、インデックス時間であなたは「標準」トークナイザの「文字列」のデフォルト値、意味として「電子メール」フィールドを定義した - 。あなたのアドレストークン: "example"と "gmail.com "! に検索時間を定義した場合、 "email"トークナイザが定義されています(つまり、最初のクエリ "[email protected]"はトークン化されていません) "または" gmail.com "(yahooでも同じ)。 2回目のクエリで "example @ google"を検索しました。これは電子メールパターン全体には含まれていないため、電子メールトークナイザは「標準」トークナイザとして機能し、「@」を切り捨てて「例」と「google "あなたのインデックスのいずれかを探しています。例は2つのドキュメントでインデックス付けされているので、両方に合っています!

あなたの住所の「例」部分のみを照合できるようにしたい場合は、検索時に「メール」アナライザを使用することはできません! ほとんどの場合、ほとんどの場合、インデックスアナライザから検索アナライザを変更しないでください。

「標準」アナライザは「gmail.com」を2つのトークンに分割しないよう注意してください!

+0

あなたの説明をありがとう。私は検索クエリの代わりに、検索クエリのプロパティを分析するアナライザを指定すると思った。 :(私が分かっているように、 'create index'ステージで電子メールのアナライザを指定する必要があります。問題は、すでに600k +文書を含むこのインデックススキームが既に存在し、この検索問題を修正する唯一の方法はこのインデックスを再作成することです。 – Hroft

+0

マッピングに「電子メール」アナライザを指定すると、新しいドキュメントがすべて解析されます。新しいマッピングを使用して新しいインデックスを作成し、古いインデックスを新しいものに再インデックスするだけです1つです。非常に簡単です。また、メール全体を一致させることができます。 – israelst

関連する問題