まとめ
char_filter に対して mapping を定義する際に、半角スペースを記述する場合は universal character name(\u0020)で記述しないとうまく認識されない。
\uXXXX 表記が使えるということを頭の片隅においておくと、役に立つことがある…かもしれない。
{
"analysis": {
"analyzer": {
"for_exact_match": {
"type": "custom",
"char_filter": [
"convert_space_filter"
],
"filter": [
"trim",
"lowercase"
],
"tokenizer": "keyword"
}
},
"char_filter": {
"convert_space_filter": {
"type": "mapping",
"mappings": [
" =>\\u0020"
]
}
}
}
}
以下はおまけ。
ことのはじまり
文字列fieldに対して、スペースを含めて完全一致するかどうかのクエリを投げたいけど、全角スペースと半角スペースは同一に扱いたい、みたいな場面に遭遇した。
例えば
"name" という文字列 field に対して、"山田 太郎" というデータが入っているとする。(完全一致させるための field 定義についてはここでははしょります)
この時に、投げるクエリが "山田 太郎" でも "山田 太郎" でも完全一致しているとみなしたい。
また、全角スペースで区切られている"山田 花子"のようなデータについても、投げるクエリが "山田 花子" でも "山田 花子" でも完全一致しているとみなしたい。
ダメな設定例
最初は以下のように char_filter を設定していた。
{
"char_filter": {
"convert_space_filter": {
"type": "mapping",
"mappings": [
" => "
]
}
}
}
が、これだと意図通りには動かなかった(全角スペースは空文字に変換されて扱われてしまった)。
手元で軽く確認してみたところ mapping の文字列表現("{before}=>{after}")においては、{before}, {after}の前後の半角スペースは trim されてしまう様子。
なので、何かしらの文字を半角スペースに置換して扱いたい、みたいな場合には、半角スペースは \u0020 と表記する必要がありますよー、というだけの話。