<備忘録> Elasticsearch、Kibana、Sudachi環境を構築する


はじめに

Elasticsearch、Kibana、Sudachiをゼロから構築する手順を記します。
また、Sudachiのプラグインの設定を変更し、トークナイズの挙動を変える手順まで記します。

環境

環境 バージョン
OS Ubuntu 18.04.3 LTS
Java OpenJDK 1.8.0_232
Elasticsearch 7.5.1
Kibana 7.5.1

Elasticsearchのインストール

カーネルパラメータを変更しておく

Elasticsearchが利用可能なメモリマップを増やしておきます。

$ sudo vi /etc/sysctl.d/99-sysctl.conf
vm.max_map_count = 262144

$ sudo sysctl --system

Elasticsearchのダウンロードと展開

公式サイトでElasticsearchをダウンロードします。
あるいはwgetで直接入手可能です。

$ wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.5.1-linux-x86_64.tar.gz

ダウンロードが完了したら解凍・配置します。
配置先は/opt/elasticsearchとしました。
root権限では起動できないようで、当該ディレクトリの所有者を適切なユーザに設定しておきます。

$ tar xvzf elasticsearch-7.5.1-linux-x86_64.tar.gz
$ sudo mv elasticsearch-7.5.1 /opt/elasticsearch
$ sudo chown -R /opt/elasticsearch [GROUP:USER]

環境変数の設定

Elasticsearchのルートディレクトリを環境変数ES_HOMEに設定します。

export ES_HOME=/opt/elasticsearch

Elasticsearchの設定を変更する

ここではシングルノードで動作させ、ローカル以外からもアクセス可能とするように設定します。

$ vi /opt/elasticsearc/config/elasticsearch.yml
network.host: 0.0.0.0
discovery.seed_hosts: ["127.0.0.1", "[::1]"]
discovery.type: single-node

Elasticsearchの起動

Elasticsearchの起動は以下の通りです。-dオプションでバックグラウンドで動作します。

$ cd /opt/elasticsearch
$ ./bin/elasticsearch -d -p pid

Webブラウザで http://[ホスト]:9200 にアクセスすると、以下のように表示されます。

{
  "name" : [サーバ名],
  "cluster_name" : "elasticsearch",
  "cluster_uuid" : "dudQ9w_mR9i3_JbJOod7Zw",
  "version" : {
    "number" : "7.5.1",
    "build_flavor" : "default",
    "build_type" : "tar",
    "build_hash" : "3ae9ac9a93c95bd0cdc054951cf95d88e1e18d96",
    "build_date" : "2019-12-16T22:57:37.835892Z",
    "build_snapshot" : false,
    "lucene_version" : "8.3.0",
    "minimum_wire_compatibility_version" : "6.8.0",
    "minimum_index_compatibility_version" : "6.0.0-beta1"
  },
  "tagline" : "You Know, for Search"
}

また、http://[ホスト]:9200/_cat/health?v にアクセスすると、クラスタの状況を確認できます。

epoch      timestamp cluster       status node.total node.data shards pri relo init unassign pending_tasks max_task_wait_time active_shards_percent
1577875702 10:48:22  elasticsearch yellow          1         1      4   4    0    0        1             0                  -                 80.0%

Kibanaのインストール

Kibanaのダウンロードと展開

公式サイトでKibanaをダウンロードします。
あるいはwgetで直接入手可能です。

$ wget https://artifacts.elastic.co/downloads/kibana/kibana-7.5.1-linux-x86_64.tar.gz

ダウンロードが完了したら解凍・配置します。
配置先は/opt/kibanaとしました。

$ tar xvzf kibana-7.5.1-linux-x86_64.tar.gz
$ sudo mv kibana-7.5.1-linux-x86_64 /opt/kibana

Kiabanaの設定を変更する

KibanaとElasticsearchを接続し、リモートからもアクセス可能に設定します。

$ sudo vi /opt/kibana/config/kibana.yml
server.host: "0.0.0.0"
elasticsearch.hosts: ["http://[Elasticsearchのホスト]:9200"]

Kibanaの起動

Kibanaを起動し、Webブラウザでアクセスしてみます。

$ /opt/kibana/bin/kibana

http://[ホスト]:5601 にアクセスするとKibanaの画面が表示されます。

左側のツールバーの「Dev Tools」にアクセスするとクエリを実行できる「Console」が表示されます。
Consoleに以下のクエリを入力・実行し動作確認します。

get _cat/health?v

右側のペインに以下のように出力されます。

epoch      timestamp cluster       status node.total node.data shards pri relo init unassign pending_tasks max_task_wait_time active_shards_percent
1577881593 12:26:33  elasticsearch green           1         1      3   3    0    0        0             0                  -                100.0%

Sudachiのインストール

Elasticsearch用のプラグインをGithubから入手します。

$ git clone https://github.com/WorksApplications/elasticsearch-sudachi.git

プラグインをMavenでパッケージングします。この時、Elasticsearchのバージョンをpom.xmlに記述します。
パッケージはtarget/release/ディレクトリ配下に作成されます。

$ cd elasticsearch-sudachi
$ vi pom.xml
<elasticsearch.version>7.5.1</elasticsearch.version>

$ mvn package

無事に成功すると、BUILD SUCCESSと表示されます。
作成されたプラグインをElasticserachにインストールします。インストールするファイルはコンソールの最後に表示されるZIPファイルです。
[INFO] Building zip: /somewhere/elasticsearch-sudachi/target/releases/analysis-sudachi-elasticsearch7.5-1.3.3-SNAPSHOT.zip

$ /opt/elasticsearch/bin/elasticsearch-plugin install file:///[プラグインのパッケージファイルパス(zip)]

[=================================================] 100%??
-> Installed analysis-sudachi

正しくインストールされているか確認します。

$ /opt/elasticsearch/bin/elasticsearch-plugin list
analysis-sudachi

Sudachiの辞書のインストール

Sudachiの辞書を入手し、設定します。辞書は公式サイトから入手できます。
Sudachiの辞書にはsmall, core, fullの3種類がありますが、ここではfullを使用します。

Sudachiの辞書や設定は以下のフォルダに格納することにします。
/opt/elasticsearch/config/sudachi_tokenizer

# 辞書をダウンロードして解凍する。
$ wget https://object-storage.tyo2.conoha.io/v1/nc_2520839e1f9641b08211a5c85243124a/sudachi/sudachi-dictionary-20191224-full.zip
$ unzip sudachi-dictionary-20191224-full.zip

# Sudachiの辞書や設定用のディレクトリを作成し、辞書ファイルをコピーする。
$ mkdir /opt/elasticsearch/config/sudachi_tokenizer
$ cp sudachi-dictionary-20191224/system_full.dic /opt/elasticsearch/config/sudachi_tokenizer

Sudachiの設定にはプラグイン以外にSudachi本体が必要になるため、Githubから入手します。
そして、fullの辞書ファイル用の設定ファイル(json)をコピーします。

$ git clone https://github.com/WorksApplications/Sudachi.git
$ cp Sudachi/src/main/resources/sudachi_fulldict.json /opt/elasticsearch/config/sudachi_tokenizer/

ここで一度、ElasticsearchとKibanaを再起動しておきます。
Elasticsearchの停止と起動の例は以下の通りです。
本手順ではKibanaはフロントで動作していると思いますのでCTRL+Cで停止し、/opt/kibana/bin/kibanaを実行します。

$ cd /opt/elasticsearch
$ kill -9 `cat pid`
$ ./bin/elasticsearch -d -p pid

Sudachiの動作確認

Sudachiが正しく動作するか確認します。ここではKibanaを使って、テスト用のインデックスを作成してみます。
WebブラウザでKibana(http://[Kibanaホスト]:5601)にアクセスし、Dev ToolsのConsoleを表示します。

Elasticsearchのインデックス登録

ElasticsearchのインデックスはRDBにおけるテーブルに相当するものです。
ここではSudachiの動作確認用のインデックスを登録してみます。

Consoleに以下のようなクエリを貼り付けて実行すると、インデックスが作成されます。

PUT /test_sudachi
{
  "settings": {
    "number_of_shards": "1",
    "analysis": {
      "analyzer": {
        "sudachi_analyzer": {
          "filter": [],
          "type": "custom",
          "tokenizer": "sudachi_tokenizer"
        }
      },
      "tokenizer": {
        "sudachi_tokenizer": {
          "mode": "search",
          "type": "sudachi_tokenizer",
          "discard_punctuation": "true",
          "resources_path": "/opt/elasticsearch/config/sudachi_tokenizer/",
          "settings_path": "/opt/elasticsearch/config/sudachi_tokenizer/sudachi_fulldict.json"            
}}}}}

右ペインに以下のように表示されれば成功です。

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

また、以下のクエリを実行すると当該インデックスの設定情報が表示されます。

GET test_sudachi

Sudachiで分かち書きしてみる

実際に適当な文字列を分かち書きしてみます。Consoleに以下のクエリを入力して実行します。

GET /test_sudachi/_analyze
{ "analyzer":"sudachi_analyzer",
  "text":"私は青いペンを持っている。しかし、赤いペンは持っていない。" }

右ペインに分かち書きした結果が出力されます。

{ "tokens" : [
  { "token" : "私", "start_offset" : 0, "end_offset" : 1, "type" : "word", "position" : 0  },
  { "token" : "は", "start_offset" : 1, "end_offset" : 2, "type" : "word", "position" : 1  },
  { "token" : "青い", "start_offset" : 2, "end_offset" : 4, "type" : "word", "position" : 2  },
  { "token" : "ペン", "start_offset" : 4, "end_offset" : 6, "type" : "word", "position" : 3  },
  { "token" : "を", "start_offset" : 6, "end_offset" : 7, "type" : "word", "position" : 4  },
  { "token" : "持っ", "start_offset" : 7, "end_offset" : 9, "type" : "word", "position" : 5  },
  { "token" : "て", "start_offset" : 9, "end_offset" : 10, "type" : "word", "position" : 6  },
  { "token" : "いる", "start_offset" : 10, "end_offset" : 12, "type" : "word", "position" : 7  },
  { "token" : "しかし", "start_offset" : 13, "end_offset" : 16, "type" : "word", "position" : 8  },
  { "token" : "赤い", "start_offset" : 17, "end_offset" : 19, "type" : "word", "position" : 9  },
  { "token" : "ペン", "start_offset" : 19, "end_offset" : 21, "type" : "word", "position" : 10  },
  { "token" : "は", "start_offset" : 21, "end_offset" : 22, "type" : "word", "position" : 11  },
  { "token" : "持っ", "start_offset" : 22, "end_offset" : 24, "type" : "word", "position" : 12  },
  { "token" : "て", "start_offset" : 24, "end_offset" : 25, "type" : "word", "position" : 13  },
  { "token" : "い", "start_offset" : 25, "end_offset" : 26, "type" : "word", "position" : 14  },
  { "token" : "ない", "start_offset" : 26, "end_offset" : 28, "type" : "word", "position" : 15  }
]}

Sudachiの設定変更

Sudachiはプラグインによってトークナイズの挙動を変更できます。
ここでは、以下の2つのプラグインを使ってみます。

  • 除外する品詞の設定 (sudachi_part_of_speech)
  • 動詞と形容詞の終止形化 (sudachi_baseform)

Sudachiの挙動を変更するには、該当のインデックスの設定をREST-APIで変更する必要があります。

インデックスの変更の流れ

インデックスの設定を変更する流れは以下の通りです。

  • インデックスのクローズ
  • 設定変更
  • インデックスのオープン

インデックスのクローズ

/[インデックス]/_closeをPOSTで実行します。

KibanaのConsoleで以下を実行するとクローズします。

POST /test_sudachi/_close

結果は以下の通りです。

{
  "acknowledged" : true,
  "shards_acknowledged" : true,
  "indices" : {
    "test_sudachi" : {
      "closed" : true
}}}

インデックスの設定変更

該当のインデックスをクローズしたらインデックスの設定を変更します。
インデックスの更新は/[インデックス]/_settingsをPUTで実行します。

以下はSudachiのプラグインとしてsudachi_baseformsudachi_part_of_speechを使用するように変更しています。
また、sudachi_part_of_speechでは、除外する品詞として"接続詞","助動詞","助詞","記号","補助記号","接続詞"を指定しています。

なお指定できる品詞は、Elasticsearchプラグインの以下のファイルを参照して下さい。

elasticsearch-sudachi/src/main/resources/com/worksap/nlp/lucene/sudachi/ja/stoptags.txt

PUT /test_sudachi/_settings
{
  "settings": {
    "index": {
      "analysis": {
        "analyzer": {
          "sudachi_analyzer": {
            "filter": [
              "sudachi_baseform",
              "my_posfilter"
        ],
            "tokenizer": "sudachi_tokenizer",
            "type": "custom"
          }
        },
        "filter":{
         "my_posfilter":{
          "type":"sudachi_part_of_speech",
          "stoptags":[
            "接続詞","助動詞","助詞","記号","補助記号","接続詞"
            ]
}}}}}}

結果は以下の通りです。

{ "acknowledged" : true }

インデックスのオープン

結果は以下の通りです。

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

分かち書きしてみる

先ほどと同じ文章を分かち書きしてみます。

GET /test_sudachi/_analyze
{ "analyzer":"sudachi_analyzer",
  "text":"私は青いペンを持っている。しかし、赤いペンは持っていない。" }

結果は以下の通りです。
動詞が原形になっており、接続詞など除外した単語は出力されていません。

{ "tokens" : [
  {"token" : "私", "start_offset" : 0, "end_offset" : 1, "type" : "word", "position" : 0 },
  {"token" : "青い", "start_offset" : 2, "end_offset" : 4, "type" : "word", "position" : 2 },
  {"token" : "ペン", "start_offset" : 4, "end_offset" : 6, "type" : "word", "position" : 3 },
  {"token" : "持つ", "start_offset" : 7, "end_offset" : 9, "type" : "word", "position" : 5 },
  {"token" : "いる", "start_offset" : 10, "end_offset" : 12, "type" : "word", "position" : 7 },
  {"token" : "赤い", "start_offset" : 17, "end_offset" : 19, "type" : "word", "position" : 9 },
  {"token" : "ペン", "start_offset" : 19, "end_offset" : 21, "type" : "word", "position" : 10 },
  {"token" : "持つ", "start_offset" : 22, "end_offset" : 24, "type" : "word", "position" : 12 },
  {"token" : "いる", "start_offset" : 25, "end_offset" : 26, "type" : "word", "position" : 14 }
]}

インデックスの削除

最後に作成したインデックスの削除です。
インデックスの削除は/[インデックス]/?prettyをDELETEで実行します。

DELETE /test_sudachi?pretty

結果は以下の通りです。

{ "acknowledged" : true }

まとめ

Elasticksearch、Kibana、Sudachiをゼロから構築する手順を記しました。
ElasticsearchのREST-APIを使用してインデックスの設定を変更し、Sudachiプラグインによってトークナイズの挙動を変更してみました。