LoginSignup
12
11

More than 5 years have passed since last update.

ElasticSearchで検索のプロになる!06.検索精度上げのための設定

Last updated at Posted at 2016-02-22

前回ではtemplateを使ってインデックスに対して特定のフィールド名に対してMappingする方法を試してみました。

最初はこれでも満足なのですが
ある程度動いてくると、検索の精度に関して色々チューニングしたくなってくる。
それについて記載していきます。

まずはよくあるアルファベットの大文字、小文字

テンプレートを弄って設定を変更します。
まずはオリジナル。

{
        "template":"search*",
        "settings":{
                "analysis":{
                        "analyzer":{
                                "ja-ma-analyzer":{
                                        "type":"custom",
                                        "tokenizer":"ja-ma-tokenizer"
                                },
                                "ja-2gram-analyzer":{
                                        "type":"custom",
                                        "tokenizer":"ja-2gram-tokenizer"
                                }
                        },
                        "tokenizer":{
                                "ja-ma-tokenizer":{
                                        "type":"kuromoji_tokenizer",
                                        "mode":"normal"
                                },
                                "ja-2gram-tokenizer":{
                                        "type":"nGram",
                                        "min_gram":"2",
                                        "max_gram":"2"
                                }
                        }
                }
        },
        "mappings":{
                "_default_":{
                        "dynamic_templates":[
                        {
                                "search_text_for_ma":{
                                        "match":"text-ja-ma",
                                        "mapping":{
                                                "type":"string",
                                                "store":"no",
                                                "analyzer":"ja-ma-analyzer"
                                        }
                                }
                        },
                        {
                                "search_text_for_2gram":{
                                        "match":"text-ja-2gram",
                                        "mapping":{
                                                "type":"string",
                                                "store":"no",
                                                "analyzer":"ja-2gram-analyzer"
                                        }
                                }
                        }
                        ]
                }
        }
}
}

変更後

{
        "template":"search*",
        "settings":{
                "analysis":{
                        "filter":{
                                "greek_lowercase_filter" : {type: "lowercase", language: "greek"}
                        },
                        "analyzer":{
                                "ja-ma-analyzer":{
                                        "type":"custom",
                                        "tokenizer":"ja-ma-tokenizer",
                                        "filter": ["kuromoji_baseform", "greek_lowercase_filter", "cjk_width"]
                                },
                                "ja-2gram-analyzer":{
                                        "type":"custom",
                                        "tokenizer":"ja-2gram-tokenizer"
                                }
                        },
                        "tokenizer":{
                                "ja-ma-tokenizer":{
                                        "type":"kuromoji_tokenizer",
                                        "mode":"normal"
                                },
                                "ja-2gram-tokenizer":{
                                        "type":"nGram",
                                        "min_gram":"2",
                                        "max_gram":"2"
                                }
                        }
                }
        },
        "mappings":{
                "_default_":{
                        "dynamic_templates":[
                        {
                                "search_text_for_ma":{
                                        "match":"text-ja-ma",
                                        "mapping":{
                                                "type":"string",
                                                "store":"no",
                                                "analyzer":"ja-ma-analyzer"
                                        }
                                }
                        },
                        {
                                "search_text_for_2gram":{
                                        "match":"text-ja-2gram",
                                        "mapping":{
                                                "type":"string",
                                                "store":"no",
                                                "analyzer":"ja-2gram-analyzer"
                                        }
                                }
                        }
                        ]
                }
        }
}
}

フィルターの設定が追加されました。
各フィルターの設定内容に関しては後述するとして、試してみる。

まずは、登録してあるテンプレートを削除

curl -XDELETE http://localhost:9200/_template/main_template

んで登録

curl -XPUT http://localhost:9200/_template/main_template -d @search_template.json

テンプレート見てみる。

curl -XGET http://localhost:9200/_template/?pretty
{
  "main_template" : {
    "order" : 0,
    "template" : "search*",
    "settings" : {
      "index.analysis.filter.greek_lowercase_filter.type" : "lowercase",
      "index.analysis.tokenizer.ja-2gram-tokenizer.max_gram" : "2",
      "index.analysis.analyzer.ja-2gram-analyzer.tokenizer" : "ja-2gram-tokenizer",
      "index.analysis.analyzer.ja-2gram-analyzer.type" : "custom",
      "index.analysis.tokenizer.ja-ma-tokenizer.type" : "kuromoji_tokenizer",
      "index.analysis.tokenizer.ja-2gram-tokenizer.type" : "nGram",
      "index.analysis.analyzer.ja-ma-analyzer.filter.1" : "greek_lowercase_filter",
      "index.analysis.analyzer.ja-ma-analyzer.filter.2" : "cjk_width",
      "index.analysis.tokenizer.ja-ma-tokenizer.mode" : "normal",
      "index.analysis.analyzer.ja-ma-analyzer.filter.0" : "kuromoji_baseform",
      "index.analysis.analyzer.ja-2gram-analyzer.filter.0" : "greek_lowercase_filter",
      "index.analysis.analyzer.ja-ma-analyzer.tokenizer" : "ja-ma-tokenizer",
      "index.analysis.analyzer.ja-2gram-analyzer.filter.1" : "cjk_width",
      "index.analysis.filter.greek_lowercase_filter.language" : "greek",
      "index.analysis.analyzer.ja-ma-analyzer.type" : "custom",
      "index.analysis.tokenizer.ja-2gram-tokenizer.min_gram" : "2"
    },
    "mappings" : {
      "_default_" : {
        "dynamic_templates" : [ {
          "search_text_for_ma" : {
            "mapping" : {
              "analyzer" : "ja-ma-analyzer",
              "store" : "no",
              "type" : "string"
            },
            "match" : "text-ja-ma"
          }
        }, {
          "search_text_for_2gram" : {
            "mapping" : {
              "analyzer" : "ja-2gram-analyzer",
              "store" : "no",
              "type" : "string"
            },
            "match" : "text-ja-2gram"
          }
        } ]
      }
    },
    "aliases" : { }
  }
}

しっかり設定されているのが分かる。

さて、ここで、設定したフィルターの説明。

"greek_lowercase_filter" : {type: "lowercase", language: "greek"}

これは登録時、検索時に大文字は全て小文字に変換するもの。
これにより、大文字、小文字に関係なく検索できるようになる。

cjk_width

あとは↑これ。全角英数字を半角に直し,半角カタカナを全角に直すなど,漢字圏の文字の全半角を整えることでマッチングをしやすくします。

このあたりかも。

あとはDefultでは10件取得のものをQueryのJsonにsizeとfromを追加してPager対応しておいた。

次はこうして設定した内容が実際にどうElasticSearchで解析されるのか。
その辺を記載したいと思います。

12
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
11