ngtokuの日記

主に雑記帳です。SNSではngtokuのID取れなかったんで、別のIDでやってます。

Elasticsearch 5.1.1 on CentOS 7.3

ちょっと聞かれて気になったので、少し触ってみた。
手順は以下
1.Java 1.8インストール
2.Elasticsearchインストール
3.Kibanaインストール
4.Kuromojiインストール
5.elasticsearch_headインストール
6.軽く検証

1.Java 1.8インストール
  ここは普通にyumで。

# yum install -y java-1.8.0-openjdk-devel
# yum install -y java-1.8.0-openjdk-debuginfo --enablerepo=*debug*

2.Elasticsearchインストール
  以下を参考にして作業。
  https://www.elastic.co/guide/en/elasticsearch/reference/5.1/rpm.html

# rpm --import https://artifacts.elastic.co/GPG-KEY-elasticsearch
# vim /etc/yum.repos.d/elasticsearch.repo
[elasticsearch-5.x]
name=Elasticsearch repository for 5.x packages
baseurl=https://artifacts.elastic.co/packages/5.x/yum
gpgcheck=1
gpgkey=https://artifacts.elastic.co/GPG-KEY-elasticsearch
enabled=1
autorefresh=1
type=rpm-md

  インストールと起動。

# yum install elasticsearch
# systemctl enable elasticsearch
# systemctl start elasticsearch

  コマンドから確認

# curl http://localhost:9200
{
  "name" : "GiUG9xz",
  "cluster_name" : "elasticsearch",
  "cluster_uuid" : "AMjCeFIvRdqBdQXcGuHDHQ",
  "version" : {
    "number" : "5.1.1",
    "build_hash" : "5395e21",
    "build_date" : "2016-12-06T12:36:15.409Z",
    "build_snapshot" : false,
    "lucene_version" : "6.3.0"
  },
  "tagline" : "You Know, for Search"
}

  デフォルトではローカルホストからしかアクセスできないので、他コンピュータからもブラウザ経由で確認できるよう、設定を変更。
  https://www.elastic.co/guide/en/elasticsearch/reference/5.1/important-settings.html

# vi /etc/elasticsearch/elasticsearch.yml

# ---------------------------------- Network -----------------------------------
#
# Set the bind address to a specific IP (IPv4 or IPv6):
#
#network.host: 192.168.0.1
network.host: 0.0.0.0

  再起動。

# systemctl restart elasticsearch

  これで他マシンからも http://マシンのIPまたはホスト名:9200/ でコマンド結果と同じものを参照できる。

3.Kibanaインストール
  これまたオフィシャルのドキュメントに従い作業。
  https://www.elastic.co/guide/en/kibana/5.1/rpm.html

# rpm --import https://artifacts.elastic.co/GPG-KEY-elasticsearch
# vim /etc/yum.repos.d/kibana.repo
[kibana-5.x]
name=Kibana repository for 5.x packages
baseurl=https://artifacts.elastic.co/packages/5.x/yum
gpgcheck=1
gpgkey=https://artifacts.elastic.co/GPG-KEY-elasticsearch
enabled=1
autorefresh=1
type=rpm-md

  インストールと起動。

# yum install kibana
# systemctl enable kibana
# systemctl start kibana

  以下を参考にconfigを変更して、他マシンからも参照できる様に変更。
  https://www.elastic.co/guide/en/kibana/5.1/settings.html

# vim /etc/kibana/kibana.yml

# Specifies the address to which the Kibana server will bind. IP addresses and host names are both valid values.
# The default is 'localhost', which usually means remote machines will not be able to connect.
# To allow connections from remote users, set this parameter to a non-loopback address.
server.host: "マシンのIPまたはホスト名"

# The URL of the Elasticsearch instance to use for all your queries.
elasticsearch.url: "http://localhost:9200"

  再起動。

# systemctl restart kibana

  ブラウザで確認
  http://マシンのIPまたはホスト名:5601

4.Kuromojiインストール
  日本語の形態素解析用に、Kuromojiを導入。
  公式ページ(http://www.atilika.org/)を見るに、MeCabをサポートしていると。

# /usr/share/elasticsearch/bin/elasticsearch-plugin install analysis-kuromoji
# systemctl restart elasticsearch

  以下でplugin部分にkuromojiがあることが確認できる。
  http://マシンのIPまたはホスト名:9200/_nodes/plugins?pretty

      "plugins" : [
        {
          "name" : "analysis-kuromoji",
          "version" : "5.1.1",
          "description" : "The Japanese (kuromoji) Analysis plugin integrates Lucene kuromoji analysis module into elasticsearch.",
          "classname" : "org.elasticsearch.plugin.analysis.kuromoji.AnalysisKuromojiPlugin"
        }

  アナライザーの設定は以下のようにするのが公式の様だが、日本人の皆さんは非推奨の模様。
  うまく動かなかったり、index毎に指定するのがよろしいとの事。

# vi /etc/elasticsearch/elasticsearch.yml
index.analysis.analyzer.default.type: custom
index.analysis.analyzer.default.tokenizer: kuromoji_tokenizer

  よって今回は上記の案を使用せず、この様に指定。tokutestという、kuromojiをanalizerに指定したindexを作成。
  "mode": searchはデフォルトだそうなので、ひとまず省略。

# curl -XPUT http://localhost:9200/tokutest -d ' 
{
  "index": {
    "analysis": {
      "tokenizer": {
        "kuromoji_user_dict": {
          "type": "kuromoji_tokenizer"
        }
      },
      "analyzer": {
        "myanalyzer": {
          "type": "custom",
          "tokenizer": "kuromoji_user_dict"
        }
      }
    }
  }
}'

  ここでkuromojiを使用するときとしないときとで結果がどのように変わるか確認。
  kuromojiを使用する場合。

# curl -XPOST 'http://localhost:9200/tokutest/_analyze?analyzer=myanalyzer&pretty' -d 'iPhoneは人々の生活を一変させました。'
{
  "tokens" : [
    {
      "token" : "iPhone",
      "start_offset" : 0,
      "end_offset" : 6,
      "type" : "word",
      "position" : 0
    },
    {
      "token" : "",
      "start_offset" : 6,
      "end_offset" : 7,
      "type" : "word",
      "position" : 1
    },
    {
      "token" : "人々",
      "start_offset" : 7,
      "end_offset" : 9,
      "type" : "word",
      "position" : 2
    },
    {
      "token" : "",
      "start_offset" : 9,
      "end_offset" : 10,
      "type" : "word",
      "position" : 3
    },
    {
      "token" : "生活",
      "start_offset" : 10,
      "end_offset" : 12,
      "type" : "word",
      "position" : 4
    },
    {
      "token" : "",
      "start_offset" : 12,
      "end_offset" : 13,
      "type" : "word",
      "position" : 5
    },
    {
      "token" : "一変",
      "start_offset" : 13,
      "end_offset" : 15,
      "type" : "word",
      "position" : 6
    },
    {
      "token" : "",
      "start_offset" : 15,
      "end_offset" : 16,
      "type" : "word",
      "position" : 7
    },
    {
      "token" : "",
      "start_offset" : 16,
      "end_offset" : 17,
      "type" : "word",
      "position" : 8
    },
    {
      "token" : "まし",
      "start_offset" : 17,
      "end_offset" : 19,
      "type" : "word",
      "position" : 9
    },
    {
      "token" : "",
      "start_offset" : 19,
      "end_offset" : 20,
      "type" : "word",
      "position" : 10
    }
  ]
}

  kuromojiを使用しない場合。

# curl -XPOST 'http://localhost:9200/tokutest/_analyze?pretty' -d 'iPhoneは人々の生活を一変させました。'
{
  "tokens" : [
    {
      "token" : "iphone",
      "start_offset" : 0,
      "end_offset" : 6,
      "type" : "<ALPHANUM>",
      "position" : 0
    },
    {
      "token" : "",
      "start_offset" : 6,
      "end_offset" : 7,
      "type" : "<HIRAGANA>",
      "position" : 1
    },
    {
      "token" : "",
      "start_offset" : 7,
      "end_offset" : 8,
      "type" : "<IDEOGRAPHIC>",
      "position" : 2
    },
    {
      "token" : "",
      "start_offset" : 8,
      "end_offset" : 9,
      "type" : "<ALPHANUM>",
      "position" : 3
    },
    {
      "token" : "",
      "start_offset" : 9,
      "end_offset" : 10,
      "type" : "<HIRAGANA>",
      "position" : 4
    },
    {
      "token" : "",
      "start_offset" : 10,
      "end_offset" : 11,
      "type" : "<IDEOGRAPHIC>",
      "position" : 5
    },
    {
      "token" : "",
      "start_offset" : 11,
      "end_offset" : 12,
      "type" : "<IDEOGRAPHIC>",
      "position" : 6
    },
    {
      "token" : "",
      "start_offset" : 12,
      "end_offset" : 13,
      "type" : "<HIRAGANA>",
      "position" : 7
    },
    {
      "token" : "",
      "start_offset" : 13,
      "end_offset" : 14,
      "type" : "<IDEOGRAPHIC>",
      "position" : 8
    },
    {
      "token" : "",
      "start_offset" : 14,
      "end_offset" : 15,
      "type" : "<IDEOGRAPHIC>",
      "position" : 9
    },
    {
      "token" : "",
      "start_offset" : 15,
      "end_offset" : 16,
      "type" : "<HIRAGANA>",
      "position" : 10
    },
    {
      "token" : "",
      "start_offset" : 16,
      "end_offset" : 17,
      "type" : "<HIRAGANA>",
      "position" : 11
    },
    {
      "token" : "",
      "start_offset" : 17,
      "end_offset" : 18,
      "type" : "<HIRAGANA>",
      "position" : 12
    },
    {
      "token" : "",
      "start_offset" : 18,
      "end_offset" : 19,
      "type" : "<HIRAGANA>",
      "position" : 13
    },
    {
      "token" : "",
      "start_offset" : 19,
      "end_offset" : 20,
      "type" : "<HIRAGANA>",
      "position" : 14
    }
  ]
}

  使わない場合は日本語全部一文字ずつになってますな。
  あと、kuromojiを使用した場合はiPhoneになっているが、使用しない場合はiphoneと小文字になっている。

5.elasticsearch_headインストール
  以下によると、バージョン5はプラグイン対応していないので、自前で入れて頂戴なという事なので。
  https://github.com/mobz/elasticsearch-head
  以下を参考に導入。
  https://github.com/mobz/elasticsearch-head#running-with-built-in-server

# yum install -y npm --enablerepo=epel
# npm install -g grunt-cli
# git clone git://github.com/mobz/elasticsearch-head.git
# cd elasticsearch-head
# npm install

  他マシンからアクセスするので、 _site/app.jsのElasticsearch接続先を変更("http://localhost:9200" → "http://マシンのIPまたはホスト名:9200")。

# vi _site/app.js
this.base_uri = this.config.base_uri || this.prefs.get("app-base_uri") || "http://マシンのIPまたはホスト名:9200";

  あと、CORS (Cross-Origin Resource Sharing)対応として以下を追記したのち、

# vi /etc/elasticsearch/elasticsearch.yml 
http.cors.enabled: true                                                         
http.cors.allow-origin: "*"

  gruntで起動。

# grunt server

  elasticsearch_headに接続。デフォルトから変更していない場合、9200はElasticsearchで、headは9100。
  http://マシンのIPまたはホスト名:9100/

6.軽く検証
  例によって以下から住所データを取り込んでみた。
  http://www.post.japanpost.jp/zipcode/download.html

  以下のようなjsonファイル(zip.json)を作成し、

{"create":{"_id":"90600000"}}
{"id": 90600000,"zipcd": "0600000","created": "2017/01/02 20:00:00","updated": "2017/01/02 20:00:00","full_address_kana": "ホッカイドウサッポロシチュウオウク","full_address_kanji": "北海道札幌市中央区"}
{"create":{"_id":"90640941"}}
{"id": 90640941,"zipcd": "0640941","created": "2017/01/02 20:00:00","updated": "2017/01/02 20:00:00","full_address_kana": "ホッカイドウサッポロシチュウオウクアサヒガオカ","full_address_kanji": "北海道札幌市中央区旭ケ丘"}

  以下コマンドで一気に取り込む。データ数は124,060件。

# curl -XPOST http://localhost:9200/manholes/geo/_bulk --data-binary @zip.json

  検索はコマンドだと以下。

# curl -X  GET http://localhost:9200/tokutest/zip/_search -d '
{
  "query": {
    "match": {
      "full_address_kanji": "久留米"
    }
  }
}'

  elasticsearch_headだとこう。21msecで3,613件ヒットしたうち、(件数指定がないのでデフォルトの)先頭10件を返却している。
  
  悪くない感じ。