2016-09-30 16 views
0

私はより良い方法をお探しです。複数の条件でプレフィックスマッチを行うより簡潔な方法をお探しください

私は、ユーザーからの任意の数の入力用語(姓が姓)を持っています。私はそれぞれのプレフィックス検索を実行し、一致するもののスコアを上げたいと思います。

解析されていないprefix queryは私が今使っているものです - 下の例を参照してください。しかし、アナライザがそうでなければ何かの責任を負うことになります。それらを小文字にしてから、トークンを使って一連のプレフィックスクエリを作成し、こうして得点を上げることができます。

  1. 例入力は「Smith、Rodriguez、ROBERTS、doe」のような姓の束です。
  2. その後、私のプログラミングは、トークンにそれらを解析しにそれらを小文字に:
    スミス
    ロドリゲス
    ロバーツ
    DOE

  3. 最後に、私はそう

のようにスコアを後押しするために、複数のプレフィックスクエリを作成
"should": [ 
    { 
     "dis_max" : { 
      "tie_breaker": 1, 
      "boost": 3, 
      "queries": [ 
       { 
        "prefix" : { "surname": "doe"} 
       }, 
       { 
        "prefix" : { "surname": "rob"} 
       }, 
       { 
        "prefix" : { "surname": "rod"} 
       }, 
       { 
        "prefix" : { "surname": "smi"} 
       } 
      ] 
     } 
    } 
], 

私はこれを非効率的にやっていると思いますが、elasticsearchは私が知らないスマートな機能を提供するかもしれません。私は、私の人生を楽にするために、プレフィックスクエリの解析された形式を望みます。例えば、質問のような弾力的な質問に分析のための入力をそのまま渡すのが理想的でしょう。"someAnalyzedPrefix": {"surname": "smith rodriguez roberts doe", prefix_length: 3}私はここで少し夢を見ていますが、私はもっとカルトの解決策を探しています。

他の種類のクエリが分析の責任を引き継いで同じ結果に影響を与えることがあるのだろうかと思います。

改善のための提案はすべて歓迎します。そうでなければ、必ずしも美しいとは言えませんが、必要に応じて上のパターンに固執します。

答えて

0

エッジNGram tokenizer/filterは役に立ちます。

インデックスのみをインデックスに、search onlyアナライザを使用できます。 インデックス・アナライザは、小文字にしてエッジngramを作成します。検索アナライザにはWord Delimiter filterがあり、クエリの解析に役立ちます。 Wordデリミタフィルタを省略して、空白の代わりにStandard tokenizerを使用するだけで空白とコンマで分割することができます。ワードデリミタを使用すると、トークンを分割する方法をより詳細に制御できます。

いつでも_analyze apiを使用して、トークンの仕組みをテストできます。

インデックスセッティング:

{ 
    "settings" : { 
     "analysis" : { 
      "filter": { 
      "word_delimiter_filter": { 
        "preserve_original": "true", 
        "catenate_words": "true", 
        "catenate_all": "true", 
        "split_on_case_change": "true", 
        "type": "word_delimiter", 
        "catenate_numbers": "true", 
        "stem_english_possessive": "false" 
      }, 
      "edgengram_filter": { 
        "type":  "edge_ngram", 
        "min_gram": 3, 
        "max_gram": 3 
      } 
     }, 
     "analyzer" : { 
       "my_edge_ngram_analyzer" : { 
        "filter": [ 
         "lowercase", 
         "edgengram_filter" 
        ], 
        "type": "custom", 
        "tokenizer" : "whitespace" 
       }, 
       "my_edge_ngram_search_analyzer": { 
        "filter": [ 
        "lowercase", 
        "word_delimiter_filter", 
        "edgengram_filter" 
        ], 
        "type": "custom", 
        "tokenizer": "whitespace" 
       } 
      } 
     } 
    } 
} 

マッピング:

{ "index" : { "_index" : "edge_test", "_type" : "test_mapping", "_id" : "1" } } 
{ "surname" : "Smith" } 
{ "index" : { "_index" : "edge_test", "_type" : "test_mapping", "_id" : "2" } } 
{ "surname" : "Rodriguez" } 
{ "index" : { "_index" : "edge_test", "_type" : "test_mapping", "_id" : "3" } } 
{ "surname" : "Roberts" } 
{ "index" : { "_index" : "edge_test", "_type" : "test_mapping", "_id" : "4" } } 
{ "surname" : "Doe" } 

そして、次の検索テンプレートを使用します:

{ 
    "query" : { 
     "bool" : { 
      "should" : [{ 
        "match" : { 
         "surname_edgengrams" : { 
          "query" : "Smith, Rodriguez, ROBERTS, doe", 
          "boost" : 3 
         } 
        } 
       } 
      ] 
     } 
    } 
} 
{ 
     "properties": { 
     "surname_edgengrams": { 
      "type": "string", 
      "analyzer": "my_edge_ngram_analyzer", 
      "search_analyzer": "my_edge_ngram_search_analyzer" 
     }, 
     "surname": { 
      "type": "string", 
      "index": "not_analyzed", 
      "copy_to": [ 
       "surname_edgengrams" 
      ] 
     } 
     } 
} 

私はバルクAPIを使用して、いくつかの文書をインデックス化

結果:

{ 
    "took": 5, 
    "timed_out": false, 
    "_shards": { 
    "total": 3, 
    "successful": 3, 
    "failed": 0 
    }, 
    "hits": { 
    "total": 4, 
    "max_score": 0.14085768, 
    "hits": [ 
     { 
     "_index": "edge_test", 
     "_type": "test_mapping", 
     "_id": "1", 
     "_score": 0.14085768, 
     "_source": { 
      "surname": "Smith" 
     } 
     }, 
     { 
     "_index": "edge_test", 
     "_type": "test_mapping", 
     "_id": "3", 
     "_score": 0.14085768, 
     "_source": { 
      "surname": "Roberts" 
     } 
     }, 
     { 
     "_index": "edge_test", 
     "_type": "test_mapping", 
     "_id": "2", 
     "_score": 0.13145615, 
     "_source": { 
      "surname": "Rodriguez" 
     } 
     }, 
     { 
     "_index": "edge_test", 
     "_type": "test_mapping", 
     "_id": "4", 
     "_score": 0.065728076, 
     "_source": { 
      "surname": "Doe" 
     } 
     } 
    ] 
    } 
} 
関連する問題