Skip to main content

Elasticsearch お試し

準備

設定を作成

コンテナを起動

docker compose up -d

Kibana コンソールには、 http://localhost:5601 からアクセスできます。

Elasticsearch API を叩いて操作

環境変数を設定しておきます。

ELASTICSEARCH_ENDPOINT=http://localhost:9200
INDEX_NAME=users-test

サーバー

状態の確認

curl -G "${ELASTICSEARCH_ENDPOINT}/_cat/health?v"
curl -G "${ELASTICSEARCH_ENDPOINT}/_cat/nodes?v"
curl -G "${ELASTICSEARCH_ENDPOINT}/_cat/indices?v&s=index"
curl -G "${ELASTICSEARCH_ENDPOINT}/_cat/aliases?v&s=index"

インデックステンプレート

インデックステンプレートの確認

curl -G "${ELASTICSEARCH_ENDPOINT}/_template" | jq

スナップショットリポジトリ

スナップショットリポジトリの確認

curl -G "${ELASTICSEARCH_ENDPOINT}/_snapshot" | jq

スナップショットリポジトリの設定

ファイルシステム指定

REPOSITORY_NAME=backup
LOCATION=/var/elasticsearch/snapshot/backups
curl -X PUT "${ELASTICSEARCH_ENDPOINT}/_snapshot/${REPOSITORY_NAME}" \
-H "Content-Type: application/json" \
-d "{
\"type\": \"fs\",
\"settings\": {
\"location\": \"${LOCATION}\"
}
}"

Amazon OpenSearch の場合

REPOSITORY_NAME=backup
AWS_REGION=ap-northeast-1
BUCKET_NAME=bucket-name
ROLE_ARN=arn:aws:iam::account-id:role/role-name
curl -X PUT "${ELASTICSEARCH_ENDPOINT}/_snapshot/${REPOSITORY_NAME}" \
--aws-sigv4 "aws:amz:${AWS_REGION}:es" \
--user "${AWS_ACCESS_KEY_ID}:${AWS_SECRET_ACCESS_KEY}" \
-H "X-Amz-Security-Token: ${AWS_SESSION_TOKEN}" \
-H "Content-Type: application/json" \
-d "{
\"type\": \"s3\",
\"settings\": {
\"bucket\": \"${BUCKET_NAME}\",
\"region\": \"${AWS_REGION}\",
\"role_arn\": \"${ROLE_ARN}\"
}
}"

スナップショットリポジトリの削除

REPOSITORY_NAME=backup
curl -X DELETE "${ELASTICSEARCH_ENDPOINT}/_snapshot/${REPOSITORY_NAME}"

Amazon OpenSearch の場合

REPOSITORY_NAME=backup
curl -X DELETE "${ELASTICSEARCH_ENDPOINT}/_snapshot/${REPOSITORY_NAME}" \
--aws-sigv4 "aws:amz:ap-northeast-1:es" \
--user "${AWS_ACCESS_KEY_ID}:${AWS_SECRET_ACCESS_KEY}" \
-H "X-Amz-Security-Token: ${AWS_SESSION_TOKEN}"

スナップショット

スナップショットの確認

REPOSITORY_NAME=backup
curl -G "${ELASTICSEARCH_ENDPOINT}/_snapshot/${REPOSITORY_NAME}/_all" | jq

スナップショット名の一覧だけ

REPOSITORY_NAME=backup
curl -G "${ELASTICSEARCH_ENDPOINT}/_snapshot/${REPOSITORY_NAME}/_all" \
| jq -r ".snapshots[].snapshot"

スナップショットの取得

REPOSITORY_NAME=backup
SNAPSHOT_NAME=$(date +%Y%m%d%H%M%S)
curl -X PUT "${ELASTICSEARCH_ENDPOINT}/_snapshot/${REPOSITORY_NAME}/${SNAPSHOT_NAME}" | jq

スナップショットの削除

REPOSITORY_NAME=backup
SNAPSHOT_NAME=hoge
curl -X DELETE "${ELASTICSEARCH_ENDPOINT}/_snapshot/${REPOSITORY_NAME}/${SNAPSHOT_NAME}"

スナップショットから復元

REPOSITORY_NAME=backup
SNAPSHOT_NAME=hoge
curl -X POST "${ELASTICSEARCH_ENDPOINT}/_snapshot/${REPOSITORY_NAME}/${SNAPSHOT_NAME}/_restore" \
-H "Content-Type: application/json" \
-d "{
\"indices\": \"${indexName}\"
}" | jq

復元時に変換する場合の例

REPOSITORY_NAME=backup
SNAPSHOT_NAME=hoge
curl -X POST "${ELASTICSEARCH_ENDPOINT}/_snapshot/${REPOSITORY_NAME}/${SNAPSHOT_NAME}/_restore" \
-H "Content-Type: application/json" \
-d "{
\"indices\": \"${indexName}\",
\"index_settings\": {
\"index.analysis.filter.synonym_filter\": {
\"synonyms\": [],
\"synonyms_path\": null,
\"updateable\": null
}
}
}" | jq

インデックス設定

インデックス設定を取得

curl -G "${ELASTICSEARCH_ENDPOINT}/${INDEX_NAME}" | jq

インデックスの Mappings 設定を取得

curl -G "${ELASTICSEARCH_ENDPOINT}/${INDEX_NAME}/_mapping" | jq

インデックス設定・更新

curl -X PUT "${ELASTICSEARCH_ENDPOINT}/${INDEX_NAME}" \
-H "Content-Type: application/json" \
-d @index.json

インデックスの削除

curl -X DELETE "${ELASTICSEARCH_ENDPOINT}/${INDEX_NAME}"

エイリアス

エイリアスの設定

INDEX_NAME=test-v2
INDEX_ALIAS=test
curl -X POST "${ELASTICSEARCH_ENDPOINT}/_aliases" \
-H "Content-Type: application/json" \
-d "{
\"actions\": [
{
\"add\": {
\"index\": \"${INDEX_NAME}\",
\"alias\": \"${INDEX_ALIAS}\"
}
}
]
}"

エイリアスの削除

INDEX_NAME=test-v2
INDEX_ALIAS=test
curl -X POST "${ELASTICSEARCH_ENDPOINT}/_aliases" \
-H "Content-Type: application/json" \
-d "{
\"actions\": [
{
\"remove\": {
\"index\": \"${INDEX_NAME}\",
\"alias\": \"${INDEX_ALIAS}\"
}
}
]
}"

参照

ドキュメントの取得

DOC_ID=doc-1
curl -G "${ELASTICSEARCH_ENDPOINT}/${INDEX_NAME}/_doc/${DOC_ID}"

アナライザー

ANALYZER_NAME=search_analyzer_ja
SEARCH_TEXT=リクルートホールディングス
curl -s -X GET "${ELASTICSEARCH_ENDPOINT}/companies/_analyze" -H "Content-Type: application/json" \
-d "{\"analyzer\": \"${ANALYZER_NAME}\", \"text\": \"${SEARCH_TEXT}\"}" | jq

検索

検索 (全て)

curl -X GET "${ELASTICSEARCH_ENDPOINT}/${INDEX_NAME}/_search" \
-H "Content-Type: application/json" \
-d "{
\"query\": {
\"match_all\": {}
},
\"from\": 0,
\"size\": 10,
\"sort\": [{\"_id\": \"asc\"}]
}" | jq

検索 (取得フィールド指定)

curl -X GET "${ELASTICSEARCH_ENDPOINT}/${INDEX_NAME}/_search" \
-H "Content-Type: application/json" \
-d "{
\"_source\": [\"title\"],
\"query\": {
\"match_all\": {}
},
\"from\": 0,
\"size\": 1000,
\"sort\": [{\"_id\": \"asc\"}]
}" | jq

検索 (件数取得)

curl -X GET "${ELASTICSEARCH_ENDPOINT}/${INDEX_NAME}/_count" \
-H "Content-Type: application/json" \
-d "{
\"query\": {
\"match_all\": {}
}
}" | jq

検索 (完全一致)

curl -X GET "${ELASTICSEARCH_ENDPOINT}/${INDEX_NAME}/_search" \
-H "Content-Type: application/json" \
-d "{
\"query\": {
\"term\": {
\"tags\": \"女性\"
}
},
\"from\": 0,
\"size\": 10,
\"sort\": [{\"_id\": \"asc\"}]
}" | jq

フィールドに "type": "keyword" を指定していない場合は .keyword をつける。

curl -X GET "${ELASTICSEARCH_ENDPOINT}/${INDEX_NAME}/_search" \
-H "Content-Type: application/json" \
-d "{
\"query\": {
\"term\": {
\"tags.keyword\": \"女性\"
}
},
\"from\": 0,
\"size\": 10,
\"sort\": [{\"_id\": \"asc\"}]
}" | jq

検索 (ワイルドカード)

curl -X GET "${ELASTICSEARCH_ENDPOINT}/${INDEX_NAME}/_search" \
-H "Content-Type: application/json" \
-d "{
\"query\": {
\"wildcard\": {
\"post.extras.company.keyword\": \"21/*\"
}
}
}" | jq

検索 (Nested)

Nested Field に対して複合検索

curl -X GET "${ELASTICSEARCH_ENDPOINT}/${INDEX_NAME}/_search" \
-H "Content-Type: application/json" \
-d "{
\"query\": {
\"nested\": {
\"path\": \"categories\",
\"query\": {
\"bool\": {
\"must\": [
{
\"term\": {
\"categories.category\": \"catg2\"
}
},
{
\"term\": {
\"categories.subCategory\": \"subcatg1\"
}
}
]
}
}
}
}
}" | jq

検索 (いずれか完全一致)

複数の OR 検索は terms を使う。

curl -X GET "${ELASTICSEARCH_ENDPOINT}/${INDEX_NAME}/_search" \
-H "Content-Type: application/json" \
-d "{
\"query\": {
\"terms\": {
\"tags\": [\"女性\", \"インターン\"]
}
},
\"from\": 0,
\"size\": 10,
\"sort\": [{\"_id\": \"asc\"}]
}" | jq

検索 (NOT)

curl -X GET "${ELASTICSEARCH_ENDPOINT}/${INDEX_NAME}/_search" \
-H "Content-Type: application/json" \
-d "{
\"query\": {
\"bool\": {
\"must_not\": [
{
\"term\": {
\"tags\": \"女性\"
}
}
]
}
},
\"from\": 0,
\"size\": 10,
\"sort\": [{\"_id\": \"asc\"}]
}" | jq

検索 (match)

curl -X GET "${ELASTICSEARCH_ENDPOINT}/${INDEX_NAME}/_search" \
-H "Content-Type: application/json" \
-d "{
\"query\": {
\"match\": {
\"title\": \"起業\"
}
},
\"from\": 0,
\"size\": 10,
\"sort\": [{\"_score\": \"desc\"}]
}" | jq

検索 (match_phrase)

curl -X GET "${ELASTICSEARCH_ENDPOINT}/${INDEX_NAME}/_search" \
-H "Content-Type: application/json" \
-d "{
\"query\": {
\"match_phrase\": {
\"title\": \"起業\"
}
},
\"from\": 0,
\"size\": 10,
\"sort\": [{\"_score\": \"desc\"}]
}" | jq

検索 (AND)

curl -X GET "${ELASTICSEARCH_ENDPOINT}/${INDEX_NAME}/_search" \
-H "Content-Type: application/json" \
-d "{
\"query\": {
\"bool\": {
\"must\": [
{
\"match\": {
\"title\": \"起業\"
}
},
{
\"match\": {
\"title\": \"女性\"
}
}
]
}
},
\"from\": 0,
\"size\": 10,
\"sort\": [{\"_score\": \"desc\"}]
}" | jq
  • OR の場合は must の代わりに should を指定する

検索 (現在日時と比較)

curl -X GET "${ELASTICSEARCH_ENDPOINT}/${INDEX_NAME}/_search" \
-H "Content-Type: application/json" \
-d "{
\"query\": {
\"range\": {
\"publishDatetime\": {
\"lt\": \"now\",
\"time_zone\": \"+09:00\"
}
}
}
}" | jq

検索 (集計)

curl -X GET "${ELASTICSEARCH_ENDPOINT}/${INDEX_NAME}/_search" \
-H "Content-Type: application/json" \
-d "{
\"aggs\": {
\"group_by_category\": {
\"terms\": {
\"field\": \"category\"
}
}
},
\"size\": 0
}" | jq

ドキュメントの作成・更新

DOC_ID=doc-1
curl -X PUT "${ELASTICSEARCH_ENDPOINT}/${INDEX_NAME}/_doc/${DOC_ID}" \
-H "Content-Type: application/json" \
-d "{
\"name\": \"鈴木 太郎\"
}"

ドキュメントの部分更新

DOC_ID=doc-1
curl -X POST "${ELASTICSEARCH_ENDPOINT}/${INDEX_NAME}/_update/${DOC_ID}" \
-H "Content-Type: application/json" \
-d "{
\"doc\": {
\"name\": \"鈴木 太郎 $(date +%Y%m%d%H%M%S)\"
}
}"

ドキュメントのバルク登録

curl -X POST "${ELASTICSEARCH_ENDPOINT}/_bulk" \
-H "Content-Type: application/json" \
-d "
{\"index\": {\"_index\": \"${INDEX_NAME}\", \"_id\": \"${DOC_ID}\"}}
{\"name\": \"鈴木 太郎\"}
"

ドキュメントの削除

DOC_ID=doc-1
curl -X DELETE "${ELASTICSEARCH_ENDPOINT}/${INDEX_NAME}/_doc/${DOC_ID}"

全ドキュメントの削除

curl -X POST "${ELASTICSEARCH_ENDPOINT}/${INDEX_NAME}/_delete_by_query" \
-d '{"query": {"match_all": {}}}'