Elasticsearchとは?
Elasticsearchは全文検索エンジンサービスです。
ざっくり言うと、全文検索エンジンのApache Luceneに、検索・データ投入用のRESTfulAPIや、クラスタリング機能を追加したものです。
Javaで出来ています。
実行にはOracle JDK version 1.8.0_25
を推奨しています。
その他の入門資料です。
ElasticSearch入門 // Speaker Deck
Macへのインストール
今回はtarからのインストールを前提にします。
tar
最新版(2.0.0)を使う場合は、この方法でインストールします。
curl -L -O https://download.elastic.co/elasticsearch/release/org/elasticsearch/distribution/tar/elasticsearch/2.0.0/elasticsearch-2.0.0.tar.gz
tar -xvf elasticsearch-2.0.0.tar.gz
最新情報はInstallationを参照してください。
Homebrew
パスの設定が簡単な方法です。
brew install elasticsearch
1.7.3がインストールされます。
~ brew install elasticsearch
==> Downloading https://download.elastic.co/elasticsearch/elasticsearch/elasticsearch-1.7.3.tar.gz
######################################################################## 100.0%
==> Caveats
Data: /usr/local/var/elasticsearch/elasticsearch_shigerunakajima/
Logs: /usr/local/var/log/elasticsearch/elasticsearch_shigerunakajima.log
Plugins: /usr/local/var/lib/elasticsearch/plugins/
Config: /usr/local/etc/elasticsearch/
To have launchd start elasticsearch at login:
ln -sfv /usr/local/opt/elasticsearch/*.plist ~/Library/LaunchAgents
Then to load elasticsearch now:
launchctl load ~/Library/LaunchAgents/homebrew.mxcl.elasticsearch.plist
Or, if you don't want/need launchctl, you can just run:
elasticsearch --config=/usr/local/opt/elasticsearch/config/elasticsearch.yml
==> Summary
🍺 /usr/local/Cellar/elasticsearch/1.7.3: 34 files, 30M, built in 19 seconds
起動
cd elasticsearch-2.0.0/bin
./elasticsearch
[2015-11-16 16:13:31,357][INFO ][node ] [Awesome Android] version[2.0.0], pid[44579], build[de54438/2015-10-22T08:09:48Z]
[2015-11-16 16:13:31,358][INFO ][node ] [Awesome Android] initializing ...
[2015-11-16 16:13:31,511][INFO ][plugins ] [Awesome Android] loaded [], sites []
[2015-11-16 16:13:31,611][INFO ][env ] [Awesome Android] using [1] data paths, mounts [[/ (/dev/disk1)]], net usable_space [40.9gb], net total_space [232.6gb], spins? [unknown], types [hfs]
[2015-11-16 16:13:33,258][INFO ][node ] [Awesome Android] initialized
[2015-11-16 16:13:33,259][INFO ][node ] [Awesome Android] starting ...
[2015-11-16 16:13:33,350][INFO ][transport ] [Awesome Android] publish_address {127.0.0.1:9300}, bound_addresses {127.0.0.1:9300}, {[fe80::1]:9300}, {[::1]:9300}
[2015-11-16 16:13:33,359][INFO ][discovery ] [Awesome Android] elasticsearch/wKCH_i4zTh-wi-ibI-ab9Q
[2015-11-16 16:13:36,399][INFO ][cluster.service ] [Awesome Android] new_master {Awesome Android}{wKCH_i4zTh-wi-ibI-ab9Q}{127.0.0.1}{127.0.0.1:9300}, reason: zen-disco-join(elected_as_master, [0] joins received)
[2015-11-16 16:13:36,421][INFO ][http ] [Awesome Android] publish_address {127.0.0.1:9200}, bound_addresses {127.0.0.1:9200}, {[fe80::1]:9200}, {[::1]:9200}
[2015-11-16 16:13:36,421][INFO ][node ] [Awesome Android] started
[2015-11-16 16:13:36,449][INFO ][gateway ] [Awesome Android] recovered [0] indices into cluster_state
デフォルトのノード名(この例ではAwesome Android)は、マーブルコミックのキャラクター名からランダムに決まるそうです。
ノード名を指定して起動
クラスタ名やノード名を指定して起動することもできます。
~ ./elasticsearch --cluster.name my_cluster_name --node.name my_node_name
[2015-11-16 16:31:31,783][INFO ][node ] [my_node_name] version[2.0.0], pid[44673], build[de54438/2015-10-22T08:09:48Z]
[2015-11-16 16:31:31,784][INFO ][node ] [my_node_name] initializing ...
[2015-11-16 16:31:31,898][INFO ][plugins ] [my_node_name] loaded [], sites []
[2015-11-16 16:31:31,993][INFO ][env ] [my_node_name] using [1] data paths, mounts [[/ (/dev/disk1)]], net usable_space [40.8gb], net total_space [232.6gb], spins? [unknown], types [hfs]
[2015-11-16 16:31:33,640][INFO ][node ] [my_node_name] initialized
[2015-11-16 16:31:33,640][INFO ][node ] [my_node_name] starting ...
[2015-11-16 16:31:33,730][INFO ][transport ] [my_node_name] publish_address {127.0.0.1:9300}, bound_addresses {127.0.0.1:9300}, {[fe80::1]:9300}, {[::1]:9300}
[2015-11-16 16:31:33,740][INFO ][discovery ] [my_node_name] my_cluster_name/9GWiJ5aARim9wlvo9BJ_sA
[2015-11-16 16:31:36,778][INFO ][cluster.service ] [my_node_name] new_master {my_node_name}{9GWiJ5aARim9wlvo9BJ_sA}{127.0.0.1}{127.0.0.1:9300}, reason: zen-disco-join(elected_as_master, [0] joins received)
[2015-11-16 16:31:36,799][INFO ][http ] [my_node_name] publish_address {127.0.0.1:9200}, bound_addresses {127.0.0.1:9200}, {[fe80::1]:9200}, {[::1]:9200}
[2015-11-16 16:31:36,800][INFO ][node ] [my_node_name] started
[2015-11-16 16:31:36,813][INFO ][gateway ] [my_node_name] recovered [0] indices into cluster_state
クラスター名とノード名が何の役に立つかは、知りません。
データ構造
データ構造は三階層です。
1. index
全文検索エンジンなのでインデックスです。
検索単位です。
2. type
よく知りません。
ドキュメントの解釈方法の単位のようです。
3. document
検索対象のドキュメントです。
RESTful API
豆知識(pretty)
クエリストリングにprettyをつけるとレスポンスが読みやすくなります。
prettyなし
~ curl -XPUT 'localhost:9200/customer'
{"acknowledged":true}
prettyあり
~ curl -XPUT 'localhost:9200/customer?pretty'
{
"acknowledged" : true
}
インデックス編集 API
インデックス作成
curl -XPUT 'localhost:9200/customer'
インデックス参照
作ったインデックスを確認します
curl 'localhost:9200/_cat/indices?v' ~
health status index pri rep docs.count docs.deleted store.size pri.store.size
yellow open customer 5 1 0 0 127b 127b
各項目の意味は...
- helth:yellow デフォルトのレプリカ1で作られているけど、レプリカの割り当てがないのでyellow。レプリカが割り当てられるとgreenになります。
- index:customer インデックス名
- pri:5 プライマリーシャードの数。意味は知りません
- rep:1 レプリカの数
- docs.count:0 ドキュメント数
インデックス削除
curl -XDELETE 'localhost:9200/customer?pretty'
ドキュメント操作用RESTful API
主に次の三つです。
curl -XPUT 'localhost:9200/customer/external/1' -d '
{
"name": "John Doe"
}'
curl 'localhost:9200/customer/external/1'
curl -XDELETE 'localhost:9200/customer/external/2'
ドキュメント追加
PUTメソッドでドキュメントをPUTします。
curl -XPUT 'localhost:9200/customer/external/1?pretty' -d '
{
"name": "John Doe"
}'
- type: external
- ID: 1
を指定します。
~ curl -XPUT 'localhost:9200/customer/external/1?pretty' -d ' ~
{
"name": "John Doe"
}'
{
"_index" : "customer",
"_type" : "external",
"_id" : "1",
"_version" : 1,
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"created" : true
}
IDを指定しない時は、POSTメソッドを使います。
curl -XPOST 'localhost:9200/customer/external?pretty' -d '
{
"name": "Jane Doe"
}'
IDはランダム生成されます。
~ curl -XPOST 'localhost:9200/customer/external?pretty' -d '
{
"name": "Jane Doe"
}'
{
"_index" : "customer",
"_type" : "external",
"_id" : "AVETZfwQQYD2LWGYXctZ",
"_version" : 1,
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"created" : true
}
ドキュメント追加時にindexがなければ自動的に作ります。
~ curl -XDELETE 'localhost:9200/customer?pretty'
{
"acknowledged" : true
}
~ curl -XPUT 'localhost:9200/customer/external/1?pretty' -d '
{
"name": "John Doe"
}'
{
"_index" : "customer",
"_type" : "external",
"_id" : "1",
"_version" : 1,
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"created" : true
}
ドキュメント取得
GETメソッドでドキュメントをGETします。
curl -XGET 'localhost:9200/customer/external/1?pretty'
~ curl -XGET 'localhost:9200/customer/external/1?pretty'
{
"_index" : "customer",
"_type" : "external",
"_id" : "1",
"_version" : 1,
"found" : true,
"_source":
{
"name": "John Doe"
}
}
ドキュメント更新
更新もPUTメソッドで行います。
curl -XPUT 'localhost:9200/customer/external/1?pretty' -d '
{
"name": "John Doe"
}'
{
"_index" : "customer",
"_type" : "external",
"_id" : "1",
"_version" : 1,
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"created" : true
}
~ curl -XPUT 'localhost:9200/customer/external/1?pretty' -d '
{
"name": "John Doe1"
}'
{
"_index" : "customer",
"_type" : "external",
"_id" : "1",
"_version" : 2,
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"created" : false
}
2回PUTするとversionが上がります。
もちろん中身も更新します。
ドキュメント削除
DELETEメソッドです。
curl -XDELETE 'localhost:9200/customer/external/2?pretty'
感想
RESTful APIが美しい。