Hello! Elasticsearch.

オープンソースのサーチエンジン Elasticsearch に関連する技術ノート

Elasticsearch 日本語でフレーズ検索が必要なわけ

Kunihiko Kido
Hello! Elasticsearch.
14 min readMay 20, 2014

--

どうやら、リクエストする単語が1単語でもアナライザーで解析され、分割された最小単語単位でORで検索されるみたい!

デフォルトの仕様を確認

curl -XPOST 'localhost:9200/test/type/' -d '{ "pref_name" : "北海道" }'
curl -XPOST 'localhost:9200/test/type/' -d '{ "pref_name" : "青森県" }'
curl -XPOST 'localhost:9200/test/type/' -d '{ "pref_name" : "岩手県" }'
curl -XPOST 'localhost:9200/test/type/' -d '{ "pref_name" : "宮城県" }'
curl -XPOST 'localhost:9200/test/type/' -d '{ "pref_name" : "秋田県" }'
curl -XPOST 'localhost:9200/test/type/' -d '{ "pref_name" : "山形県" }'
curl -XPOST 'localhost:9200/test/type/' -d '{ "pref_name" : "福島県" }'
curl -XPOST 'localhost:9200/test/type/' -d '{ "pref_name" : "茨城県" }'
curl -XPOST 'localhost:9200/test/type/' -d '{ "pref_name" : "栃木県" }'
curl -XPOST 'localhost:9200/test/type/' -d '{ "pref_name" : "群馬県" }'
curl -XPOST 'localhost:9200/test/type/' -d '{ "pref_name" : "埼玉県" }'
curl -XPOST 'localhost:9200/test/type/' -d '{ "pref_name" : "千葉県" }'
curl -XPOST 'localhost:9200/test/type/' -d '{ "pref_name" : "東京都" }'
curl -XPOST 'localhost:9200/test/type/' -d '{ "pref_name" : "神奈川県" }'
curl -XPOST 'localhost:9200/test/type/' -d '{ "pref_name" : "新潟県" }'
curl -XPOST 'localhost:9200/test/type/' -d '{ "pref_name" : "富山県" }'
curl -XPOST 'localhost:9200/test/type/' -d '{ "pref_name" : "石川県" }'
curl -XPOST 'localhost:9200/test/type/' -d '{ "pref_name" : "福井県" }'
curl -XPOST 'localhost:9200/test/type/' -d '{ "pref_name" : "山梨県" }'
curl -XPOST 'localhost:9200/test/type/' -d '{ "pref_name" : "長野県" }'
curl -XPOST 'localhost:9200/test/type/' -d '{ "pref_name" : "岐阜県" }'
curl -XPOST 'localhost:9200/test/type/' -d '{ "pref_name" : "静岡県" }'
curl -XPOST 'localhost:9200/test/type/' -d '{ "pref_name" : "愛知県" }'
curl -XPOST 'localhost:9200/test/type/' -d '{ "pref_name" : "三重県" }'
curl -XPOST 'localhost:9200/test/type/' -d '{ "pref_name" : "滋賀県" }'
curl -XPOST 'localhost:9200/test/type/' -d '{ "pref_name" : "京都府" }'
curl -XPOST 'localhost:9200/test/type/' -d '{ "pref_name" : "大阪府" }'
curl -XPOST 'localhost:9200/test/type/' -d '{ "pref_name" : "兵庫県" }'
curl -XPOST 'localhost:9200/test/type/' -d '{ "pref_name" : "奈良県" }'
curl -XPOST 'localhost:9200/test/type/' -d '{ "pref_name" : "和歌山県" }'
curl -XPOST 'localhost:9200/test/type/' -d '{ "pref_name" : "鳥取県" }'
curl -XPOST 'localhost:9200/test/type/' -d '{ "pref_name" : "島根県" }'
curl -XPOST 'localhost:9200/test/type/' -d '{ "pref_name" : "岡山県" }'
curl -XPOST 'localhost:9200/test/type/' -d '{ "pref_name" : "広島県" }'
curl -XPOST 'localhost:9200/test/type/' -d '{ "pref_name" : "山口県" }'
curl -XPOST 'localhost:9200/test/type/' -d '{ "pref_name" : "徳島県" }'
curl -XPOST 'localhost:9200/test/type/' -d '{ "pref_name" : "香川県" }'
curl -XPOST 'localhost:9200/test/type/' -d '{ "pref_name" : "愛媛県" }'
curl -XPOST 'localhost:9200/test/type/' -d '{ "pref_name" : "高知県" }'
curl -XPOST 'localhost:9200/test/type/' -d '{ "pref_name" : "福岡県" }'
curl -XPOST 'localhost:9200/test/type/' -d '{ "pref_name" : "佐賀県" }'
curl -XPOST 'localhost:9200/test/type/' -d '{ "pref_name" : "長崎県" }'
curl -XPOST 'localhost:9200/test/type/' -d '{ "pref_name" : "熊本県" }'
curl -XPOST 'localhost:9200/test/type/' -d '{ "pref_name" : "大分県" }'
curl -XPOST 'localhost:9200/test/type/' -d '{ "pref_name" : "宮崎県" }'
curl -XPOST 'localhost:9200/test/type/' -d '{ "pref_name" : "鹿児島県" }'
curl -XPOST 'localhost:9200/test/type/' -d '{ "pref_name" : "沖縄県" }'
$ curl -s 'localhost:9200/test/_analyze?field=type.pref_name&pretty' -d '群馬県'|jq ".tokens[].token"
"群"
"馬"
"県"
$ curl -s 'localhost:9200/test/_analyze?field=type.pref_name&pretty' -d '東京都'|jq ".tokens[].token"
"東"
"京"
"都"
curl -s 'localhost:9200/test/type/_search?pretty' -d '
{
"query":{
"query_string":{
"default_field" : "pref_name",
"query":"東京都"
}
}
}' | jq ".hits.hits[]|{score: ._score, pref_name: ._source.pref_name}"
{
"pref_name": "東京都",
"score": 2.551233
}
{
"pref_name": "京都府",
"score": 0.7797127
}
curl -s 'localhost:9200/test/type/_search?pretty' -d '
{
"query":{
"query_string":{
"default_field" : "pref_name",
"query":"都京東"
}
}
}' | jq ".hits.hits[]|{score: ._score, pref_name: ._source.pref_name}"
{
"pref_name": "東京都",
"score": 2.551233
}
{
"pref_name": "京都府",
"score": 0.7797127
}
curl -s 'localhost:9200/test/type/_search?pretty' -d '
{
"query":{
"query_string":{
"default_field" : "pref_name",
"query":"東 OR 京 OR 都"
}
}
}' | jq ".hits.hits[]|{score: ._score, pref_name: ._source.pref_name}"
{
"pref_name": "東京都",
"score": 2.551233
}
{
"pref_name": "京都府",
"score": 0.7797127
}

やっぱり、リクエストする単語が1単語でもアナライザーで解析され、分割された最小単語単位でORで検索されていますよ!

検索結果の詳細を確認する方法(explain)

$ curl 'localhost:9200/test/type/_search?pretty' -d '
{
"explain": true,
"query":{
"query_string":{
"default_field" : "pref_name",
"query":"東京都"
}
}
}'
{
...
"description" : "weight(pref_name:東 in 6) [PerFieldSimilarity], result of:",
...
"description" : "weight(pref_name:京 in 6) [PerFieldSimilarity], result of:",
...
"description" : "weight(pref_name:都 in 6) [PerFieldSimilarity], result of:",
...
}

正確にマッチさせたい場合はフレーズ検索

curl -s 'localhost:9200/test/type/_search?pretty' -d '
{
"explain": true,
"query":{
"query_string":{
"default_field" : "pref_name",
"query":"\"東京都\""
}
}
}'
{
...
"description" : "weight(pref_name:\"東 京 都\" in 6) [PerFieldSimilarity], result of:",
...
}
curl -s 'localhost:9200/test/type/_search?pretty' -d '
{
"explain": true,
"query":{
"query_string":{
"default_field" : "pref_name",
"query":"\"東京都\" \"群馬県\""
}
}
}'

まとめ

--

--

Hello! Elasticsearch.
Hello! Elasticsearch.

Published in Hello! Elasticsearch.

オープンソースのサーチエンジン Elasticsearch に関連する技術ノート

Kunihiko Kido
Kunihiko Kido

Responses (1)