今回はMappingする際に設定できる
Analyzer
というものを触ってみたいと思います。
その前に・・・
前回作成した
mapping.json
の補足です"user_id": {
"type": "string",
"index": "not_analyzed"
},
user_id
のフィールドに対してtypeがstringでindexがnot_analyzedとなっています。この
not_analyzed
ですが構文解析せず完全一致で検索します。
例えば・・
user_idに
ユニークなフィールドにはつけたほうがいいやつです。
user_idに
ABCD-1234
というデータが入ってる場合にnot_analyzed
を指定せずにABCDや1234で検索した場合ABCD-5678
でもEFGH-1234
でもヒットしてしまいます。ユニークなフィールドにはつけたほうがいいやつです。
次に・・
"created": {
"type": "date",
"format": "strict_date_optional_time||epoch_millis"
}
ですが、JSONは日時のデータ型を持ってないので、以下の3つの方法で表現します。
- 文字列 ('2016-01-01'や'2016/01/01 10:10:50'など)
- 数値 (
1970/01/01 00:00:00
からの経過ミリ秒(UTC)) - 数値 (
1970/01/01 00:00:00
からの経過秒(UTC))
↑の
strict_date_optional_time||epoch_millis
は2になりますAnalyzer
一つのanalyzerは一つの
サンプルとして以下のMappingを
※このサンプルでは
Tokenizer
と0個以上のTokenFilters
で構成されます。サンプルとして以下のMappingを
analyzer_test
というIndexに作成します。※このサンプルでは
TokenFilters
は使用してません。{
"settings": {
"analysis": {
"analyzer": {
"my_analyzer": {
"tokenizer": "my_tokenizer"
}
},
"tokenizer": {
"my_tokenizer": {
"type": "nGram",
"min_gram": "2",
"max_gram": "2",
"token_chars": [
"letter",
"digit"
]
}
}
}
},
"mappings": {
"sample": {
"properties": {
"text": {
"type": "string",
"analyzer": "my_analyzer"
},
"subtext": {
"type": "string",
"analyzer": "my_analyzer"
}
}
}
}
}
my_tokenizer
として設定している箇所で、nGram
とありますが、これはN個文字を区切って検索するものです。ここでは
min_gram
とmax_gram
に2と設定しているので2文字毎区切って検索を行います。
早速
analyzer_test_mapping.json
として保存しインポート$ curl -X POST 192.168.33.180:9200/analyzer_test -d @analyzer_test_mapping.json
ちゃんと設定できているか確認してみます。
$ curl -X GET '192.168.33.180:9200/analyzer_test/_mapping/sample/?pretty'
{
"analyzer_test" : {
"mappings" : {
"sample" : {
"properties" : {
"subtext" : {
"type" : "string",
"analyzer" : "my_analyzer"
},
"text" : {
"type" : "string",
"analyzer" : "my_analyzer"
}
}
}
}
}
}
ちゃんと設定できているので、データ登録して動作を確認してみます。
$ curl -X PUT 192.168.33.180:9200/analyzer_test/sample/1 -d '{
"text" : "abcdefg", "subtext" : "123456789"
}'
まずは、分割された2文字に対して検索。
$ curl -XPOST '192.168.33.180:9200/analyzer_test/_search?pretty' -d
'{ "query": { "match": { "text": "cd" } } }'
{
"took" : 3,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"failed" : 0
},
"hits" : {
"total" : 1,
"max_score" : 0.11506981,
"hits" : [ {
"_index" : "analyzer_test",
"_type" : "sample",
"_id" : "1",
"_score" : 0.11506981,
"_source" : {
"text" : "abcdefg",
"subtext" : "123456789"
}
} ]
}
}
これはヒットしますが、1文字で検索してみると、
$ curl -XPOST '192.168.33.180:9200/analyzer_test/_search?pretty' -d
'{ "query": { "match": { "text": "c" } } }'
{
"took" : 8,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"failed" : 0
},
"hits" : {
"total" : 0,
"max_score" : null,
"hits" : [ ]
}
}
最低2文字で単語を分割してる為こちらはヒットしません。
結構細かくAnalyzerを調整できるので、チューニング次第でヒット率が上がったり下がったりしそうですね。
結構細かくAnalyzerを調整できるので、チューニング次第でヒット率が上がったり下がったりしそうですね。
0 件のコメント:
コメントを投稿