2016-09-30 6 views
2

最近私はelasticsearchで作業を始めました。これが「基本的な」質問である場合は謝罪します。私はまた、ESバージョン1.3から2.4(!)への移行作業中に、プロセス中にいくつかの問題が生じたり、もはや動作しなかったクエリなどがなくなったり(「悪い」結果を出す) 。私はこれらの問題のいくつかを修正しましたが、これはスタンパです。ElasticSearch fieldNormは常に1です

どのように関連性スコアリングが行われたかについては、docsを読んでいます。私のインデックスはパターントークナイザ(単語に分割されたもの)で処理され、小文字のフィルタとngramフィルタ(最小長1、最大長3)でヒットされます。

文字「a」を検索すると、比較的短いドキュメントが最初に表示されます。たとえば、 "asian"(目的のトークンの2つのインスタンスが含まれています)は、 "Astasia-abasia"(6つあります)より高いスコアにする必要があります。比例性は、項の頻度および場のノルムによって説明される。すばらしいです!これは私が欲しいものです。しかし...

実際に "アジアン"は最初の5000ヒットには登場しません!私が?explainを見ると、fieldNormは存在しますが、常に1に等しいのがわかります。これはなぜですか?どうすれば修正できますか?

私が使用しているインデックスコードはここにある:

{ 
    "settings": { 
     "number_of_shards": 1, 
     "number_of_replicas": 0, 
     "analysis": { 
      "analyzer": { 
       "ngram_analyzer": { 
        "tokenizer": "pattern_tokenizer", 
        "filter": [ "lowercase", "ngram_filter" ] 
       } 
      }, 
      "tokenizer": { 
       "pattern_tokenizer": { 
        "type": "pattern", 
        "pattern": "[\\]\\[{}()/ ,:;\"&]+" 
       } 
      }, 
      "filter": { 
       "ngram_filter": { 
        "type": "ngram", 
        "min_gram": "1", 
        "max_gram": "3" 
       } 
      } 
     } 
    }, 
    "mappings": { 
     "terms": { 
      "properties": { 
       "code": { 
        "analyzer": "ngram_analyzer", 
        "search_analyzer": "keyword", 
        "type": "string", 
        "norms": { 
         "enabled": true, 
         "loading": "eager" 
        } 
       }, 
       "codeAbbr": { 
        "analyzer": "ngram_analyzer", 
        "search_analyzer": "keyword", 
        "type": "string", 
        "norms": { 
         "enabled": true, 
         "loading": "eager" 
        } 
       }, 
       "term": { 
        "analyzer": "ngram_analyzer", 
        "search_analyzer": "keyword", 
        "type": "string", 
        "norms": { 
         "enabled": true, 
         "loading": "eager" 
        } 
       } 
      } 
     } 
    } 
} 

私は、私も規範属性を指定する必要がありますように感じることはありません(私は上記のように感じるデフォルトでなければなりません)が、それはdoesnの問題ありません。私がそれらを取り出したり入れたりすると、答えは同じです。 fieldNormを正しく動作させるにはどうすればいいですか?

+0

クエリを共有できますか?あなたの説明の結果は?また、フィールドの1つにいくつの用語が存在するかを確認できますか?フィールドで用語の集計を行い、「sum_other_doc_count」の値を確認することができます。https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-terms-aggregation.html – jay

+0

@ジェイは返事をしてくれてありがとうございます。残念ながら、私が仕事場に帰るまで、私はそれを手に入れませんでした。そして、土曜日に正確な質問と結果を得ることはできません。それは、関連情報が上記の質問にあると私は信じていた。クエリは、単一の用語 "a"を持つ一致クエリです –

+0

私は、用語の数を求めた理由 - fieldNormは1/squareroot(項数)として計算されます。これは、fieldNormより小さい項の数が多いことを意味します。すべてのフィールドでngramが使用されます。これは、用語の数がv v高いことを意味します。あなたが見る値1 - 私が読んだところから、値は1 +フィールドNormのデフォルトのインデックス時間の増加です。値は1バイトに格納されるため、精度が低下します。 – jay

答えて

2

答えは私が予想したものと多少異なることが判明しました。私は、この回答が、私が費やした時間を他の誰かが助けることを願っています私は読んだことのある文書のどこにでもこれを見たことはありませんでしたが、実験によって発見しました。私の非常に具体的な問題はで、ngramフィルタではなくngramトークナイザを使用して解決できますが、なぜこれが説明されるのかを教えてください。

fieldNormが計算されたときの問題はであり、これがngramフィルタとトークナイザが異なる理由の1つです。

fieldNormは、文書1/sqrt(#tokens)で指定された式を使用して、文書内のトークンの数に基づいています。あなたが尋ねる人に応じて、分母に+1があるかもしれませんし、そうでないかもしれませんが、この質問のために本当に重要ではありません。重要なことは、をフィルタリングする前に#tokens数字がだがの後にと計算されるということです。

私が知る限り、これはドキュメント内のトークンの数を変更する唯一のものであるため、ngramとエッジngramフィルタで重要です。ドキュメントの中で目立って説明されていないのはおそらくこの理由です。しかし、これがなぜ重要なのかを説明するために、いくつかのユースケースがあります。

  1. 文書が長いフレーズで構成されているとします。あなたは標準のトークナイザなどでトークン化します。あなたのフィールドノルムは基本的に言葉の数に基づいています。これはあなたが望むものかもしれません。あなたのユースケースに依存します。このように検索すると、単語数の点でより短い文書が優先されます(長い単語を使用しても検索には不利益はありません)。代わりにngramトークナイザを使用すると、fieldNormは文字数に比例します。だから、あなたが少しの言葉をたくさん使うと、私はそれより少ないが大きな言葉を使うと、私たちの得点は同じになるかもしれません。通常はあなたが望むものではありません。

  2. あなたの文書が単一の単語または非常に短いフレーズ(私のようなもの)で構成されているとします。標準的なトークナイザを使用してトークン化すると、ほとんどのドキュメントはfieldNorm 1を持ちます。しかし、私は短い単語に優先順位をつける(一般的な単語の近似として)ので、これは役に立たない。代わりに、ngramトークナイザを使用します。したがって、長い単語は下にプッシュされ、短い単語は先頭に移動します。

関連する問題