why
日本語の部分一致検索をしたかった。
https://www.elastic.co/guide/en/elasticsearch/reference/current/multi-fields.html
ES の公式ガイドを見ると
PUT indexName
{
"mappings": {
"properties": {
"keyName": {
"type": "text",
"fields": {
"raw": {
"type": "keyword"
}
}
}
}
}
}
その index の mapping を PUT で更新すれば良いようだ。
fileds の raw の type を keyword にすれば
少文字大文字で区別せずに検索できるようになるらしい?
実際に自分のインデックスに打って確かめてみる
これを打つと text の raw の 中身が keyword で作られた。
{
"error": {
"root_cause": [
{
"type": "illegal_argument_exception",
"reason": "mapper [name] cannot be changed from type [text] to [keyword]"
}
],
"type": "illegal_argument_exception",
"reason": "mapper [name] cannot be changed from type [text] to [keyword]"
},
"status": 400
}
PUT だから本体の text を keyword に変更しようとしてみたが
変更できないとエラーがでた。
"type": "illegal_argument_exception",
"reason": "mapper [name.raw] cannot be changed from type [keyword] to [text]"
中の raw という keyword も
PUT で text <-> keyword に変更することはできなかった。
{
"acknowledged": true
}
同じ値でリクエストすると「知ってるよ」ってレスポンスが来る。
よって、クエリを間違えているわけではなさそうだ。
raw について調べてみる
https://stackoverflow.com/a/38538096
city: New York の場合は
new と york のトークンが city フィールドに入っている
city.raw のフィールドには New York の完全なキーワードが入っている。
こういうことらしい。
dan に DaN でリクエストしてみる。
親である text の dan のデータにリクエストしてみる
GET /customer/_search
{
"query": {
"match": { "name": "DaN" }
}
}
}
前回作った dan のデータが
"hits": [
{
"_index": "customer",
"_id": "3",
"_score": 0.9808291,
"_source": {
"name": "dan"
}
}
]
DaN の検索でヒットした。
https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping-types.html#text-search-types
既にデフォルトの text 型なら大文字小文字区別なくひっかかる?
da では引っかからない。
https://www.elastic.co/guide/en/elasticsearch/reference/current/keyword.html#keyword
反対に keyword 型は
- ID
- HostAddress
- Status Code
- Zip Code
こういう形式の決まっている値に向いているっぽい。
keyword は単語で分割して保存されないので、match で部分一致検索できないらしい。
keyword 型で検索する
https://stackoverflow.com/questions/41722812/elasticsearch-can-i-query-the-raw-field
これを読むと、raw を検索するには re-index をしないといけないが
クエリはあっているらしい。
GET /customer/_search
{
"query": {
"match": { "name.keyword": "dan" }
}
}
}
"hits": [
{
"_index": "customer",
"_id": "3",
"_score": 0.9808291,
"_source": {
"name": "dan"
}
}
]
なので、中身の keyword に dan でかけると取れて
GET /customer/_search
{
"query": {
"match": { "name.keyword": "dAn" }
}
}
}
"hits": []
dAn でかけると取れなかった。
まとめ
Elastic Search の index に対して key value のセットを追加すると、
デフォルトでは text 型で保存される。
text 型は単語で分割して保存されるので、__search match を打つだけで
アルファベットでは、大文字小文字の曖昧検索が実装できる。
一方、大文字小文字を厳密に検索したい場合は、
GET /customer/_search
{
"query": {
"match": { "name.keyword": "dan" }
}
}
}
このように keyName.keyword で打てば
厳密に検索できる。
Top comments (0)