社内向けにElasticSearch(全文検索)の検証を行っています。
検証中に、理解できない事象に遭遇したため、ElastiSearchについて知見を持っている方のアドバイスを頂きたいと考えています。
事象
テキストをインデックスし、インデックスした「同一のテキスト」でmatch_phraseした際に、マッチを得られない。
「同一のテキスト」でクエリしているため、マッチが得られる想定。
環境
以下の環境で事象が再現している。
- ElasticSearch 6.8.1 & Kibana(共にWindows10上にホスト)
- sudachi(構文解析器)
- sudachi full版 辞書(small版辞書では事象は再現しない。同様にkuromojiでも事象は再現しない。)
- kibana discover & kibana dev tool
再現手順(kibana dev toolを想定)
1. elastic sudachi導入
導入手順は、後述の環境構築手順を参考。
辞書は、full版を導入する。
2. マッピング設定
プレーンなsudachi analyzerとフィールドを設定する。
json
1PUT mytestindex 2{ 3 "settings": { 4 "number_of_shards": 1, 5 "number_of_replicas": 0, 6 "index.query.default_field": [ 7 "sudachi_field" 8 ], 9 "analysis": { 10 "analyzer": { 11 "default": { 12 "tokenizer": "sudachi_tokenizer", 13 "type": "custom" 14 }, 15 //kuromojiで検証する場合 16 "kuromoji_analyzer": { 17 "type": "custom", 18 "tokenizer": "kuromoji_tokenizer" 19 } 20 }, 21 "tokenizer": { 22 //full版辞書では、mode: normal,search,extended共にマッチが得られない。small版辞書では、満足する結果が得られている。 23 "sudachi_tokenizer": { 24 "type": "sudachi_tokenizer", 25 "mode": "search", 26 "resources_path": "sudachi_tokenizer" //デフォルトで、<elasticsearch_config>/sudachi_tokenizer/system_core.dic を参照する 27 } 28 } 29 } 30 }, 31 "mappings": { 32 "_doc": { 33 "properties": { 34 "sudachi_field": { 35 "type": "text", 36 "analyzer": "default", 37 "search_analyzer": "default", 38 "store": true, 39 "fielddata": true, 40 "fields": { 41 "keyword": { 42 "type": "keyword", 43 "ignore_above": 256 44 } 45 } 46 } 47 } 48 } 49 } 50}
2. インデックス
テストケースを登録する。
POST _doc/_bulk { "index" : { "_index" : "mytestindex", "_type": "_doc", "_id" : "1" } } { "sudachi_field": "十一代目 市川海老蔵"} { "index" : { "_index" : "mytestindex", "_type": "_doc", "_id" : "2" } } { "sudachi_field": "十一代目市川海老蔵"} { "index" : { "_index" : "mytestindex", "_type": "_doc", "_id" : "3" } } { "sudachi_field": "11代目 市川海老蔵"} { "index" : { "_index" : "mytestindex", "_type": "_doc", "_id" : "4" } } { "sudachi_field": "11代目市川海老蔵"}
3. クエリの発行
クエリを発行する。
json
1GET mytestindex/_search 2{ 3 "query": { 4 "bool": { 5 "must": [], 6 "filter": [ 7 { 8 "bool": { 9 "filter": [ 10 { 11 "bool": { 12 "should": [ 13 //================================================= 14 //ヒットしないケース 15 //================================================= 16 { 17 "match_phrase": { 18 "sudachi_field": "十一代目市川海老蔵" 19 } 20 }, 21 { 22 "match_phrase": { 23 "sudachi_field": "十一代目 市川海老蔵" 24 } 25 }, 26 { 27 "match_phrase": { 28 "sudachi_field": "11代目市川海老蔵" 29 } 30 }, 31 { 32 "match_phrase": { 33 "sudachi_field": "11代目 市川海老蔵" 34 } 35 }, 36 { 37 "match_phrase": { 38 "sudachi_field": "11代目市川" 39 } 40 }, 41 { 42 "match_phrase": { 43 "sudachi_field": "十一代目 市川" 44 } 45 }, 46 { 47 "match_phrase": { 48 "sudachi_field": "十一代目市川" 49 } 50 }, 51 { 52 "match_phrase": { 53 "sudachi_field": "11代目 市川" 54 } 55 } 56 //================================================= 57 //ヒットするケース 58 //================================================= 59 //,{ 60 // "match_phrase": { 61 // "sudachi_field": "十一代目" 62 // } 63 //} 64 //,{ 65 // "match_phrase": { 66 // "sudachi_field": "11代目" 67 // } 68 //} 69 //,{ 70 // "match_phrase": { 71 // "sudachi_field": "市川" 72 // } 73 //} 74 //,{ 75 // "match_phrase": { 76 // "sudachi_field": "海老蔵" 77 // } 78 //} 79 //,{ 80 // "match_phrase": { 81 // "sudachi_field": "市川海老蔵" 82 // } 83 //} 84 //,{ 85 // "match_phrase": { 86 // "sudachi_field": "市川 海老蔵" 87 // } 88 //} 89 ], 90 "minimum_should_match": 1 91 } 92 } 93 ] 94 } 95 } 96 ], 97 "should": [], 98 "must_not": [] 99 } 100 } 101}
4. 結果確認
json
1{ 2 "took" : 1, 3 "timed_out" : false, 4 "_shards" : { 5 "total" : 1, 6 "successful" : 1, 7 "skipped" : 0, 8 "failed" : 0 9 }, 10 "hits" : { 11 "total" : 0, 12 "max_score" : null, 13 "hits" : [ ] 14 } 15}
5. 検証
- [十一代目 市川]等で検索した場合、解析結果は[十一代目 市川海老蔵]となっていることから、[十一代目 市川]にマッチしないのは納得できる
- [十一代目 市川海老蔵]等で検索した場合、同一の解析結果が得られると想定しているため、マッチしないのは納得できない
- sudachiのsmall辞書で解析した場合はフルネーム単位で解析されず、苗字・名前単位で解析されるためマッチした
- kuromojiで解析した場合はフルネーム単位で解析されず、苗字・名前単位で解析されるためマッチした
GET mytestindex/_analyze
{ "tokens" : [ { "token" : "十一", "start_offset" : 0, "end_offset" : 2, "type" : "word", "position" : 0 }, { "token" : "代目", "start_offset" : 2, "end_offset" : 4, "type" : "word", "position" : 1, "positionLength" : 2 }, { "token" : "代", "start_offset" : 2, "end_offset" : 3, "type" : "word", "position" : 1 }, { "token" : "目", "start_offset" : 3, "end_offset" : 4, "type" : "word", "position" : 2 }, { "token" : "市川海老蔵", "start_offset" : 4, "end_offset" : 9, "type" : "word", "position" : 3, "positionLength" : 2 }, { "token" : "市川", "start_offset" : 4, "end_offset" : 6, "type" : "word", "position" : 3 }, { "token" : "海老蔵", "start_offset" : 6, "end_offset" : 9, "type" : "word", "position" : 4 } ] }
環境構築手順
elastic search6.8.1のインストール
elastic sudachi導入手順
- 参考 sudachi構築手順
- elasticsearch-sudachi gitリポジトリ
- git clone コマンド(elasticsearch 6.8.1用) git clone -b v6.8.1-1.3.1-SNAPSHOT https://github.com/WorksApplications/elasticsearch-sudachi.git
elastic sudachi辞書配置
full辞書をダウンロードし、フォルダに配置する。
- https://github.com/WorksApplications/Sudachi
- 配置先:Windowsの場合 C:\ProgramData\Elastic\Elasticsearch\config\sudachi_tokenizer\system_core.dic(デフォルトはelastisearch config配下のsudachi_tokenizer/system_core.dicを参照します。)
見解
sudachiの構文解析の品質は良いと感じている。
full版の辞書を利用すると、辞書による固有名詞の理解が多くなり、分析面でメリットがある一方、
単語単位での分かち書きと固有名詞トークンが生成されるため、フレーズ一致の面でデメリットが生じる。
自社要件としては、漏れなくフレーズに一致できることが求められているため、small版辞書が要件を満たしそうだ。
sudachiは辞書が充実していることがウリだが、検索面では辞書によるデメリットも生じるため、辞書はsmallの方が挙動を理解しやすく思える。
辞書がsmallの場合、kuromojiに対する優位性は現在分かっていない。
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/02/29 18:44