Edited at

Elasticsearchで、分かち書き(kuromoji:形態素解析)したqueryを_searchする。

analyzeのkuromoji適用は色々なところに書いてあったが、

searchのkuromoji適用はあまり書いていなかったので、ここにメモします。


動作環境


  • macOS Mojave 10.14.2

  • Java 11.0.2

  • Elasticsearch 6.6.0

  • kibana 6.6.0

  • kuromoji

Elasticsearchは全文検索エンジンです。

Kibanaは、データ可視化ツールです。ポート5601で確認できます。

kuromojiは、日本語の形態素解析エンジンです。


インストール

Java入れたりElasticsearch入れたりのあたりは、以下の記事がとても参考になります。

参考:はじめての Elasticsearch

ありがとうございました。

基本のキは↑を参考にしてください。


そもそも押さえておきたいこと

_analyzeと_searchは違うっぽい。


  • analyze …文章をGET(POST?)すると、文章解析した結果がコンソールに表示される。

  • search …検索


kuromoji(形態素解析)の適用

localhost:5601kibana を立ち上げ、左メニューの Dev Tools で操作するものとします。

また、Elasticsearchの言葉として

index/type/document

という構造になっています。

・mappingは変更できない。

・さらに、elasticsearch6.0からは複数type×。

ということを踏まえて、インデックスから分けて作り、比較します。


・インデックスの設定

はじめに基盤となるインデックスを作っておきましょう。


DevTools

PUT /test_index

{
"settings": {
"analysis": {
"analyzer": {
"hoge_kuromoji_analyzer": {
"type": "custom",
"tokenizer": "kuromoji_tokenizer"
}
}
}
}
}

analyzerのところに"hoge_kuromoji_analyzer"というものを作っています。※名前は任意の名前で良い。

中にはtokenizerというものを設定していて、形態素解析してくれます。

"tokenizer": "kuromoji_tokenizer"という書き方は変えてはいけません。

参考:Elasticsearchを日本語で使う設定のまとめ

test_indexというインデックスが作成されました。


・タイプとドキュメント

ドキュメントをいっぺんに作成しておきます。


DevTools

POST /test_index/test_type/_bulk

{"index": {"_id": 1}}
{"title" : "メモ1","sentence" : "梅酒は水"}
{"index": {"_id": 2}}
{"title" : "メモ2","sentence" : "養命酒は水"}
{"index": {"_id": 3}}
{"title" : "メモ3","sentence" : "私はリンゴが大好きです"}
{"index": {"_id": 4}}
{"title" : "メモ4","sentence" : "妹の好物は真っ赤なリンゴです"}


・データの確認

データが入っているかどうかは以下のコマンドで確認しましょう。


DevTools

GET /test_index/test_type/_search

{
"explain": true,
"query": {
"match_all": {}
}
}

これで基礎設定はOKです。


/インデックス/_analyze

文章をGETすると、文章解析した結果がコンソールに表示されます。

すでにインデックスの設定でanalyzerの箇所にkuromojiを設定してあります。

それを呼び出して使います。


普通のanalyze


普通のanalyze

GET /test_index/_analyze

{
"text": "梅酒が好き"
}

【結果】

梅/酒/が/好/き

一文字ひともじ、分析されます。


kuromoji適用analyze


kuromoji適用analyze

GET /test_index/_analyze

{
"analyzer": "hoge_kuromoji_analyzer",
"text": "梅酒が好き"
}

【結果】

梅酒/が/好き

形態素解析(分かち書き)されて、分析されます。


/インデックス/_search

searchにkuromojiを適用させる場合は、mappingに色々と書くようです。

現在のmapping状況の確認はこちら

GET /test_index/_mapping

※elasticsearch6.0から複数typeのmappingができなくなりました!oh...


普通のsearch


普通のsearch

GET /test_index/test_type/_search

{
"query": {
"match": {
"sentence": "梅酒が好き"
}
}
}

【結果】

0.8630463 "私はリンゴが大好きです" 

0.83355963 "養命酒は水"

0.59321976 "妹の好物は真っ赤なリンゴです"

0.5753642 "梅酒は水"


kuromoji適用search

searchにもkuromojiを適用させるには、mappingに書き込まなければいけません。

しかし、既存のmappingを変更することはできないので、一番最初(indexを作るとき)に一緒に設定します。


・インデックス作成


/kuromoji_index/kuromoji_type/を作ります。

PUT /kuromoji_index

{
"settings": {
"analysis": {
"analyzer": {
"hoge_kuromoji_analyzer": {
"type": "custom",
"tokenizer": "kuromoji_tokenizer"
}
}
}
},
"mappings": {
"kuromoji_type": {
"properties": {
"title": {
"type": "text",
"analyzer": "hoge_kuromoji_analyzer"
},
"sentence": {
"type": "text",
"analyzer": "hoge_kuromoji_analyzer"
}
}
}
}
}

kuromoji_type"tokenizer": "kuromoji_tokenizer"が設定されました。

これで、searchで飛んできても、分かち書きが適用されます。


・ドキュメント入れ込み

データを入れ込みます。

POST /kuromoji_index/kuromoji_type/_bulk

{"index": {"_id": 1}}
{"title" : "メモ1","sentence" : "梅酒は水"}
{"index": {"_id": 2}}
{"title" : "メモ2","sentence" : "養命酒は水"}
{"index": {"_id": 3}}
{"title" : "メモ3","sentence" : "私はリンゴが大好きです"}
{"index": {"_id": 4}}
{"title" : "メモ4","sentence" : "妹の好物は真っ赤なリンゴです"}


・データの確認

GET /kuromoji_index/kuromoji_type/_search

{
"explain": true,
"query": {
"match_all": {}
}
}


・kuromoji適用search


kuromoji適用されているので、そのインデックスでsearch

GET /kuromoji_index/kuromoji_type/_search

{
"query": {
"match": {
"sentence": "梅酒が好き"
}
}
}

【結果】

0.2876821 "梅酒は水"

0.2876821 "私はリンゴが大好きです" 

精度は落ちましたが、 梅酒/が/好き で検索された結果がきています。

"explain": true,を追加すると細かいことが書かれていますがちょっとよくわかりません。


explainを追加してみる

GET /kuromoji_index/kuromoji_type/_search

{
"explain": true,
"query": {
"match": {
"sentence": "梅酒が好き"
}
}
}


その他参考記事


コンソールからやる場合

kibanaのDevToolsを使わず、コンソールからやる場合は

Elasticsearch v6から色々変わっているようです。

Content-Typeの指定が必須となりました。以下のようにコンソールに書いてください。

curl -H "Content-Type: application/json" -X PUT 'localhost:9200/hoge_index' -d '

{
"settings": {
"analysis": {
"analyzer": {
"my_kuromoji_analyzer": {
"type": "custom",
"tokenizer": "kuromoji_tokenizer"
}
}
}
},
"mappings": {
"natsume": {
"properties": {
"title": {
"type": "text",
"index": "true",
"analyzer": "my_kuromoji_analyzer"
},
"sentence": {
"type": "text",
"index": "true",
"analyzer": "my_kuromoji_analyzer"
}
}
}
}
}'