Elasticsearch token filterの順番

Token filterは順番に注意しないと意図通り動かないケースがあるため注意する必要がある。Synonym Graph Token Filterとlowercase token filterを利用するケースで具体的にみていく。

Synonym Graph Token Filter

synonym_graph Token Filterを使用すると、analysisの過程で複数単語の同義語展開を簡単に処理できます。

Lowercase token filter

トークンテキストを小文字に変換する。 たとえば、lowercase filterは DoG→dogの変換をする。当然だが同じフィールドのsearch analyzerとanalyzerの両方定義されるべきである。

token filterの順番

token filterの順番は下のfilterの配列の順番で表現される。

 "analyzer" : {
                   "synonym" : {
                       "tokenizer" : "standard",
                       "filter" : [ "lowercase","synonym_graph"]
                   },
                    ...
 }

synonymとlowercaseはlowercaseを先にあてて、そのあと同義語展開させるのが普通である。その際に同義語辞書は小文字に統一されてある必要がある。そうでないと大文字の単語のクエリにたいして同義語展開ができないからだ。

正しい順番

先にlowercase  filterで「正規化」しているため、大文字小文字の差分を吸収して同義語展開できる。


PUT /synonym_lowercase_index
{
   "settings": {
       "index" : {
           "analysis" : {
               "analyzer" : {
                   "synonym" : {
                       "tokenizer" : "standard",
                       "filter" : [ "lowercase","synonym_graph"]
                   },
                   "lowanalyze" : {
                     "tokenizer" : "standard",
                     "filter" : ["lowercase"]
                   }
               },
               "filter" : {
                   "synonym_graph" : {
                       "type" : "synonym_graph",
                       "lenient": true,
                       "synonyms" : ["foo, bar, baz"]
                   }
               }
           }
       }
   },
   "mappings" : {
     "properties" : {
       "foo" : {
         "type" : "text",
         "analyzer" : "lowanalyze",
         "search_analyzer": "synonym"
       }
     }
   }
}

PUT synonym_lowercase_index/_doc/1
{
 "foo": "bar"
}


PUT synonym_lowercase_index/_doc/2
{
 "foo": "baz"
}
PUT synonym_lowercase_index/_doc/3
{
 "foo": "Baz"
}

PUT synonym_lowercase_index/_doc/4
{
 "foo": "BAR"
}

GET /synonym_lowercase_index/_search
{
   "query": {
       "match" : {
           "foo" : {
             "query" : "foo"
           }
       }
   }
}
GET /synonym_lowercase_index/_search
{
   "query": {
       "match" : {
           "foo" : {
             "query" : "Foo"
           }
       }
   }
}

GET /synonym_lowercase_index/_analyze
{
 "analyzer": "synonym", 
 "text" : "foo"
}


GET /synonym_lowercase_index/_analyze
{
 "analyzer": "synonym", 
 "text" : "Foo"
}


フィルターの順番を間違えた場合

先に同義語展開しようとするが、大文字は同義語展開されない。

PUT /synonym_lowercase_inverseoreder_index
{
   "settings": {
       "index" : {
           "analysis" : {
               "analyzer" : {
                   "synonym" : {
                       "tokenizer" : "standard",
                       "filter" : [ "synonym_graph","lowercase"]
                   },
                   "lowanalyze" : {
                     "tokenizer" : "standard",
                     "filter" : ["lowercase"]
                   }
               },
               "filter" : {
                   "synonym_graph" : {
                       "type" : "synonym_graph",
                       "lenient": true,
                       "synonyms" : ["foo, bar, baz"]
                   }
               }
           }
       }
   },
   "mappings" : {
     "properties" : {
       "foo" : {
         "type" : "text",
         "analyzer" : "lowanalyze",
         "search_analyzer": "synonym"
       }
     }
   }
}

PUT synonym_lowercase_inverseoreder_index/_doc/1
{
 "foo": "bar"
}


PUT synonym_lowercase_inverseoreder_index/_doc/2
{
 "foo": "baz"
}
PUT synonym_lowercase_inverseoreder_index/_doc/3
{
 "foo": "Baz"
}

PUT synonym_lowercase_inverseoreder_index/_doc/4
{
 "foo": "BAR"
}

GET /synonym_lowercase_inverseoreder_index/_search
{
   "query": {
       "match" : {
           "foo" : {
             "query" : "foo"
           }
       }
   }
}
GET /synonym_lowercase_inverseoreder_index/_search
{
   "query": {
       "match" : {
           "foo" : {
             "query" : "Foo"
           }
       }
   }
}

GET /synonym_lowercase_inverseoreder_index/_analyze
{
 "analyzer": "synonym", 
 "text" : "foo"
}


GET /synonym_lowercase_inverseoreder_index/_analyze
{
 "analyzer": "synonym", 
 "text" : "Foo"
}

この記事が気に入ったらサポートをしてみませんか?