アゴ乗せ日記

適当なポジティブ日記

スポンサーリンク

Amazon Elasticsearchで全角半角大文字小文字の検索結果を同じにする

若手検索ワードが半角だとHITしないのですが、PHPの関数で全角に変換してから検索させましょうか

ワイそれElasticsearchでできへんの?

若手できました!


Amazon Elasticsearch Service だが、管理が楽だ。 ユーザ辞書の登録ができない点が少し懸念だが、なんとかやっていけそうな感じはある。

さて、「全角半角大文字小文字の検索結果を同じにする」ということだが、文字列の正規化で実現できる。

やりかた

indexのsettingsで"char_filter" : ["icu_normalizer"]を設定する。

{
    "settings": {
        "index": {
            "analysis": {
                "analyzer": {
                    "default_analyzer": {
                        "tokenizer": "kuromoji_tokenizer",
                        "char_filter" : ["icu_normalizer"]  ←こいつを設定
                    },

(省略)

設定しないとどうなるのか

例えば半角で『スーパー』と登録しようとすると、

GET test_index/_analyze
{
  "analyzer": "default_analyzer",
  "text": "スーパー"
} 

アナライズの結果、以下のように半角の「スーパー」のまま登録される。検索時も同様だ。

{
  "tokens": [
    {
      "token": "スーパー",
      "start_offset": 0,
      "end_offset": 5,
      "type": "word",
      "position": 0
    }
  ]
}

このままだと全角の『スーパー』で検索されたときにHITしない。なぜなら半角の『スーパー』で登録されているからだ。

設定するとどうなるのか

同じ半角の『スーパー』でも

GET test_index/_analyze
{
  "analyzer": "default_analyzer",
  "text": "スーパー"
} 

文字の正規化が行われ、今度は全角の『スーパー』として登録される。

{
  "tokens": [
    {
      "token": "スーパー",
      "start_offset": 0,
      "end_offset": 5,
      "type": "word",
      "position": 0
    }
  ]
}

この正規化は登録される文字はもちろん、検索時のキーワードにも適用される。 なので、検索ワードが半角の『スーパー』であっても正規化が適用されて、全角の『スーパー』として検索されるのだ。

よって、全角半角のゆれを吸収することになる。

大文字小文字も同様

例えばローマ字で『aBc』と大文字小文字が混合している場合も

GET test_index/_analyze
{
  "analyzer": "default_analyzer",
  "text": "aBc"
} 

小文字(lowercase)で統一される。登録時も検索時も同じ動きとなる。

{
  "tokens": [
    {
      "token": "abc",
      "start_offset": 0,
      "end_offset": 3,
      "type": "word",
      "position": 0
    }
  ]
}

簡単に全角半角大文字小文字対応ができるわけだ。

おわり

最近技術ネタが増えてきたが、育児をしていないわけではない。

以上!

スポンサーリンク