Elasticsearchとは公式サイトに以下記載ある通り、Elastic Stackの中核をなすプロダクトです。
Elasticsearchは、様々なユースケースを解決する分散型RESTful検索/分析エンジンです。 データを一元的に格納することで、超高速検索や、関連性の細かな調整、パワフルな分析が大規模に、手軽に実行可能になります。Elastic Stackの心臓部となるプロダクトです。
私がこれまでよく使ってきた方法としてはロギングに使用して、調査時に全文検索するという形ですが、その他にも様々な用途で使用ができます。
ローカル環境構築
今回は気軽に構築する方法として公式dockerイメージを使ってローカル環境を構築する手順を紹介します。
使用するのは公式イメージ
入門用のリポジトリを用意してますので、まずはクローンしてみてください。
今回使用するのはクローンしたリポジトリ内の lesson-01
に入っています。
その中の
services:
es01:
image: elasticsearch:8.4.0
container_name: es01
environment:
- node.name=es01
- cluster.name=es-docker-cluster
- discovery.type=single-node
- xpack.security.enabled=false
ulimits:
memlock:
soft: -1
hard: -1
volumes:
- data01:/usr/share/elasticsearch/data
ports:
- 9200:9200
networks:
- elasticstack
volumes:
data01:
driver: local
networks:
elasticstack:
driver: bridge
を実行してみましょう。
docker-compose up -d
ここまで終えたら一度 http://localhost:9200/ にアクセスしてみましょう。
以下のような情報が表示されていればOKです。
{
"name" : "es01",
"cluster_name" : "es-docker-cluster",
"cluster_uuid" : "piL1NiCDTaqeGWYM2CJeDQ",
"version" : {
"number" : "8.4.0",
"build_flavor" : "default",
"build_type" : "docker",
"build_hash" : "f56126089ca4db89b631901ad7cce0a8e10e2fe5",
"build_date" : "2022-08-19T19:23:42.954591481Z",
"build_snapshot" : false,
"lucene_version" : "9.3.0",
"minimum_wire_compatibility_version" : "7.17.0",
"minimum_index_compatibility_version" : "7.0.0"
},
"tagline" : "You Know, for Search"
}
インデックス作成
現状はまだElasticsearchを起動しただけで何もない状況です。
まずはインデックスを作成していきます。
インデックスは相互に関連づけられたドキュメントの集合です。
インデックスとドキュメントの関係性は以下の図のような感じです。
早速 users
という名前のインデックスを作成してみます。
curl -X PUT 'localhost:9200/users?pretty'
{
"acknowledged" : true,
"shards_acknowledged" : true,
"index" : "users"
}
ちなみに pretty
をパラメータに付与することでレスポンスのJSONが整形されます。
インデックス確認
_cat
はCompact and Aligned Text APIの略のようです。
(自分は最初Linuxの cat
コマンドと同じく concatenate
の略だと思ってました...)
indices
は index
の複数形です。
v
パラメータは verbose output
切り替えのためのオプションで付けることでキー名が表示されます。
curl -X GET 'localhost:9200/_cat/indices?v'
health status index uuid pri rep docs.count docs.deleted store.size pri.store.size
yellow open users 81oNdJlaTRSANvhC6AFMjg 1 1 0 0 225b 225b
できてますね。
続いて users
インデックスを取得してみると aliases
や mappings
が空で settings
のみ設定されていることを確認できます。
alias
や mapping
については初回から扱うと複雑になるので、次回以降に説明します。
curl -X GET 'localhost:9200/users?pretty'
{
"users" : {
"aliases" : { },
"mappings" : { },
"settings" : {
"index" : {
"routing" : {
"allocation" : {
"include" : {
"_tier_preference" : "data_content"
}
}
},
"number_of_shards" : "1",
"provided_name" : "users",
"creation_date" : "1661394180559",
"number_of_replicas" : "1",
"uuid" : "81oNdJlaTRSANvhC6AFMjg",
"version" : {
"created" : "8040099"
}
}
}
}
}
ドキュメントの追加
それではドキュメントを作成してみましょう。
curl -X POST 'localhost:9200/users/_doc/?pretty' -H 'Content-Type:application/json' -d '{
"name": "foo",
"address": "foo bar",
"age": 100
}'
{
"_index" : "users",
"_id" : "I1xy4oIBJ9pAjFjtFcni",
"_version" : 1,
"result" : "created",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 0,
"_primary_term" : 1
}
作成されました。
POSTメソッドでid指定なしで作成したので、 _id
はランダムで生成されています。
ドキュメントの確認
curl -X GET 'localhost:9200/_search?pretty' -H 'Content-Type:application/json' -d '{
"query": {
"bool": {
"must": [
{"match":{"name":"foo"}}
]
}
}
}'
{
"took" : 38,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 0.2876821,
"hits" : [
{
"_index" : "users",
"_id" : "I1xy4oIBJ9pAjFjtFcni",
"_score" : 0.2876821,
"_source" : {
"name" : "foo",
"address" : "foo bar",
"age" : 100
}
}
]
}
}
ドキュメントの更新
先ほど作成したドキュメントの age
を 10
に更新してみます。
先ほどPOSTした際のレスポンスで返ってきたIDを指定しjsonの一部を修正してPUTすると更新されます。
下記の _doc
の後ろは置き換えて実行してください。
curl -X PUT 'localhost:9200/users/_doc/I1xy4oIBJ9pAjFjtFcni?pretty' -H 'Content-Type:application/json' -d '{
"name": "foo",
"address": "foo bar",
"age": 10
}'
{
"_index" : "users",
"_id" : "I1xy4oIBJ9pAjFjtFcni",
"_version" : 2,
"result" : "updated",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 1,
"_primary_term" : 1
}
実際に更新されたか確認してみます。
curl -X GET 'localhost:9200/_search?pretty' -H 'Content-Type:application/json' -d '{
"query": {
"bool": {
"must": [
{"match":{"name":"foo"}}
]
}
}
}'
age
が 100
から 10
になっていることが確認できます。
{
"took" : 1001,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 0.2876821,
"hits" : [
{
"_index" : "users",
"_id" : "I1xy4oIBJ9pAjFjtFcni",
"_score" : 0.2876821,
"_source" : {
"name" : "foo",
"address" : "foo bar",
"age" : 10
}
}
]
}
}
ドキュメントの削除
先ほど作ったドキュメントを削除してみましょう。
更新時同様にIDは置き換えてください。
curl -X DELETE 'localhost:9200/users/_doc/I1xy4oIBJ9pAjFjtFcni?pretty'
{
"_index" : "users",
"_id" : "I1xy4oIBJ9pAjFjtFcni",
"_version" : 3,
"result" : "deleted",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 2,
"_primary_term" : 1
}
もう一度 name:foo
ドキュメントにアクセスしようとすると
curl -X GET 'localhost:9200/_search?pretty' -H 'Content-Type:application/json' -d '{
"query": {
"bool": {
"must": [
{"match":{"name":"foo"}}
]
}
}
}'
hitしなくなりました。
{
"took" : 401,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 0,
"relation" : "eq"
},
"max_score" : null,
"hits" : [ ]
}
}
インデックス削除
ここで最後にインデックスの削除も試してみましょう。
curl -X DELETE 'localhost:9200/users?pretty'
{
"acknowledged" : true
}
以上で、ローカル環境にElasticsearch環境〜インデックス作成〜ドキュメント操作までの一連の流れとなります。
最後はお片付け。
docker-compose down -v
次回へ続く(はず)