Shohhei1126's Blog

Elasticsearch5で簡単な日本語検索

前回の続きでデータ登録して検索するところまでやってみる。

以下を参考にした。

kuromoji_tokenizer | Elasticsearch Plugins and Integrations [5.5] | Elastic

kuromojiをインストール

前回入れてなかったので追加。

/usr/share/elasticsearch/bin/elasticsearch-plugin install analysis-kuromoji

インデックス作成

/etc/elasticsearch/elasticsearch.ymlindex.xxx とindexレベルの設定をするとエラーになる。 どうやらバージョン5から設定ファイルにはnodeレベルのものだけ書くようになった模様。

java.lang.IllegalArgumentException: node settings must not contain any index level settings

なのでREST APIで設定する。

$ curl -XPUT 'localhost:9200/items?pretty' -d '{
  "settings": {
    "index": {
      "analysis": {
        "tokenizer": {
          "my_tokenizer": {
            "type": "kuromoji_tokenizer",
            "mode": "search"
          }
        },
        "analyzer": {
          "my_analyzer": {
            "type": "custom",
            "tokenizer": "my_tokenizer"
          }
        }
      },
      "number_of_shards": 1,
      "number_of_replicas": 0
    }
  }
}'

{
  "acknowledged" : true,
  "shards_acknowledged" : true
}

ElasticseachのアーキテクチャはElasticsearch 日本語で全文検索 その1となっている模様。フィルターはオプションなのでとりあえず kuromoji_tokenizer を使って my_analyzer を作成した。ちなみに PUT /{インデックス名} でインデックスが作られるけどRESTなので馴染みあって分かりやすい。

"number_of_shards": 1"number_of_replicas": 0 はデフォルトだとそれぞれ5と1なので以下のようになって気持ち悪いので設定。もちろん本番はよしなにやらないとだけど遊ぶだけなので。

スッキリ。

データを入れて検索してみる

PUT /{インデックス}/{タイプ}/{ID} で登録出来る。{ID} 無しで POST を使うと自動でIDが割り振られて登録されるようだ。

$ curl -XPUT 'localhost:9200/items/article/1?pretty' -d'{"description": "東京スカイツリーは、東京都墨田区押上一丁目にある電波塔(送信所)である。"}'
$ curl -XPUT 'localhost:9200/items/article/2?pretty' -d'{"description": "スカイラインは日産自動車が製造・販売している乗用車である。"}'

ここまでくればあたりがつくが GET /{インデックス}/{タイプ}/{ID} で取得できる。

$ curl -XGET 'localhost:9200/items/article/1?pretty'
{
  "_index" : "items",
  "_type" : "article",
  "_id" : "1",
  "_version" : 1,
  "found" : true,
  "_source" : {
    "description" : "東京スカイツリーは、東京都墨田区押上一丁目にある電波塔(送信所)である。"
  }
}

検索はインデックス複数指定できたりタイプも絞れたりするようだがとりあえずシンプルに GET /{インデックス}/_search?pretty&q={クエリ} を使ってみる。 クエリは 東京スカイツリー をUTF-8でURLエンコードしたもの。

$ curl -XGET 'localhost:9200/items/_search?pretty&q=%e6%9d%b1%e4%ba%ac%e3%82%b9%e3%82%ab%e3%82%a4%e3%83%84%e3%83%aa%e3%83%bc'
{
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "failed" : 0
  },
  "hits" : {
    "total" : 1,
    "max_score" : 2.4738975,
    "hits" : [
      {
        "_index" : "items",
        "_type" : "article",
        "_id" : "1",
        "_score" : 2.4738975,
        "_source" : {
          "description" : "東京スカイツリーは、東京都墨田区押上一丁目にある電波塔(送信所)である。"
        }
      }
    ]
  }
}

今日はこの辺で。