2

SQL では、SQL LIKE を使用して電子メール アドレスをかなりうまく検索できます。

「stack@domain.com」という電子メールで、「stack」、「@domain.com」、「domain.com」、または「domain」を検索すると、目的の電子メール アドレスが返されます。

ElasticSearch で同じ結果を得るにはどうすればよいですか?

nGram、edgeNGram、uax_url_email などで遊んでみましたが、検索結果はかなり悪いものでした。間違っている場合は修正してください。次のことを行う必要があるようです。

  1. index_analyzer 用
    • 「キーワード」、「空白」、または「uax_url_email」トークナイザーを使用して、メールがトークン化されないようにする
      • しかし、ワイルドカードクエリは機能しないようです(少なくともタイヤでは)
    • フィルターには「nGram」または「edgeNGram」を使用します
      • 「first-second」を検索すると「first@domain.com」が表示されるなど、常に不要な結果が多すぎます。
  2. search_analyzer 用
    • nGramをしないでください

1 つの実験コード

tire.settings :number_of_shards => 1,
            :number_of_replicas => 1,
            :analysis => {
                :filter => {
                    :db_ngram  => {
                        "type"     => "nGram",
                        "max_gram" => 255,
                        "min_gram" => 3 }
                },
                :analyzer => {
                    :string_analyzer => {
                        "tokenizer"    => "standard",
                        "filter"       => ["standard", "lowercase", "asciifolding", "db_ngram"],
                        "type"         => "custom" },
                    :index_name_analyzer => {
                        "tokenizer"    => "standard",
                        "filter"       => ["standard", "lowercase", "asciifolding"],
                        "type"         => "custom" },
                    :search_name_analyzer => {
                        "tokenizer"    => "whitespace",
                        "filter"       => ["lowercase", "db_ngram"],
                        "type"         => "custom" },
                    :index_email_analyzer => {
                        "tokenizer"    => "whitespace",
                        "filter"       => ["lowercase"],
                        "type"         => "custom" }
                }
            } do
    mapping do
      indexes :id,           :index    => :not_analyzed
      indexes :name,         :index_analyzer => 'index_name_analyzer', :search_analyzer => 'search_name_analyzer'
      indexes :email,        :index_analyzer => 'index_email_analyzer', :search_analyzer => 'search_email_analyzer'
    end
end

うまく機能しない特定のケース:

  • ハイフン付きのメール (email-hyphen@domain.com など)
  • 先頭または末尾のクエリ文字列 '@'
  • 完全一致
  • 「 @ 」などのワイルドカードを使用して検索すると、非常に予期しない結果が得られます。

「aaa@email.com」、「aaa_0@email.com」、「aaa-0@email.com」があるとします。「aaa」を検索すると、「aaa@a.com」「aaa-0@email.コム。「aaa*」で検索するとすべて表示されますが、「aaa-*」では何も表示されません。では、完全一致のワイルドカードクエリを実行するにはどうすればよいでしょうか。これらのタイプのクエリでは、さまざまなトークナイザー/アナライザーでほぼ同じ結果が得られます。

マッピングを変更するたびにこれらを行います: Model.tire.index.delete Model.tire.create_elasticsearch_index Model.tire.index.import Model.all

参考文献:

4

1 に答える 1

0

あなたが達成しようとしていることを考えるとKeywordAnalyzer、アナライザーの合理的な選択かもしれませんが、WhitespaceAnalyzer.

クエリの解析と分析で問題が発生していると思われますが、クエリの方法を実際には説明していません。最も単純なケースは、用語またはプレフィックスクエリを使用することです。

StandardAnalyzer一貫して適用され、クエリが正しい限り、ほとんどの場合、ここで目的を果たすように思えます(「aaa_0」と「aaa-0」を区別するのは問題になります)。

于 2013-08-28T21:42:22.407 に答える