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": {}}}'