클러스터의 건강 상태를 확인해보자. 다음 API의 응답 중에서 status 필드의 값이 중요하다.
curl localhost:9200/_cluster/health
{
"cluster_name": "opensearch_homebrew",
"status": "green",
"timed_out": false,
"number_of_nodes": 3,
"number_of_data_nodes": 3,
"discovered_master": true,
"discovered_cluster_manager": true,
"active_primary_shards": 0,
"active_shards": 0,
"relocating_shards": 0,
"initializing_shards": 0,
"unassigned_shards": 0,
"delayed_unassigned_shards": 0,
"number_of_pending_tasks": 0,
"number_of_in_flight_fetch": 0,
"task_max_waiting_in_queue_millis": 0,
"active_shards_percent_as_number": 100.0
}
이미 생성되어 있는 index 목록을 조회하는 것도 필요하다.
curl localhost:9200/_cat/indices
다음과 같이 index별 상태를 확인할 수 있다.
green open test_index -pyXIxp3R4CsT_5yiB11qw 1 3 401 0 23.1kb 23.1kb
yellow open ebooks -pyXQ51ax1ctt_29flzj2m 1 3 598 0 30.5kb 30.5kb
이제부터는 특정 인덱스 "test_index"에 저장하는 것을 전제로 하겠다.
POST method로 임의의 json 문서를 insert할 수 있다.
curl -s -X POST localhost:9200/test_index/_doc -H "Content-Type: application/json" -d '{"num": 30}'
Bash의 while loop를 이용하여 1000건 insert하는 예제는 다음과 같다.
total_count=1000
i=0
while [ "$i" -lt "$total_count" ]; do
echo -n "."
curl -s -X POST localhost:9200/test_index/_doc -H "Content-Type: application/json" -d '{"num": '"$i"'}' > /dev\
/null
i=$((i+1))
done
_doc API에 접근하여 POST method로 다음과 같은 json 문서 데이터를 insert한다.
{ "num": 1 }
한 건씩 적재하면 성능 상 손해가 생기는데, 이 문제를 해결하는 방법으로 bulk API를 사용하면 된다. (다른 문서 curl을_이용한_ElasticSearch_bulk_API_사용 에서 자세히 다루고 있다.)
이 코드 예제는 0부터 999까지의 num 값을 가지는 문서를 Bash의 while loop를 이용하여 반복해서 insert하고 있다.
curl -s localhost:9200/test_index/_count
_count API를 이용하여 test_index에 저장되어 있는 문서의 갯수를 확인할 수 있다. 그러나 많은 문서를 빠른 속도로 insert한 직후에 바로 count를 조회하면 정확한 값이 조회되지 않는다. 이럴 경우에 _refresh API를 이용하여 문서의 메타데이터/통계를 갱신해줄 필요가 있다.
curl -s localhost:9200/test_index/_refresh
curl -s localhost:9200/test_index/_count
단순히 문서를 조회할 때는 _doc API를 이용해도 되지만
curl -s localhost:9200/test_index/_doc/gwbBCIgBbIjXWaPdciBv
id를 미리 정의해서 등록해두었고 그걸 확인할 수 있을 때만 가능하다.
일반적인 검색은 조건에 일치하는 문서들을 일부 검색한 다음에, pagination을 통해서 조금씩 더 조회하는 절차를 따르는데, ElasticSearch에서는 이 기능을 scroll이라고 한다. 다음과 같이 scroll을 이용할 수 있다.
100건씩 1분짜리 세션을 지정해서 모든 문서를 조회하는 요청은 다음과 같다. 1h로 해도 된다.
curl -s localhost:9200/test_index/_search\?scroll=1m -H 'Content-Type: application/json' -d '{"size": 100, "query": {"match_all": {} } }'
응답에서 scroll id를 얻어야 한다.
curl -s localhost:9200/test_index/_search\?scroll=1m -H 'Content-Type: application/json' -d '{"size": 100, "query": {"match_all": {} } }' | jq -r ._scroll_id
jq 명령을 추가로 설치할 필요가 있다.
scroll id는 FGluY2x1ZGVfY29udGV4dF91dWlkDXF1ZXJ5QW5kRmV0Y2gBFmdVRksxd0VMUUhteEl5SWxCSWxhQWcAAAAAAATk3RZDMFVpdWZUQVNhdXRKaVhpTEdRYkVB로 확인되었다.
curl -s localhost:9200/_search/scroll -H 'Content-Type: application/json' -d '{"scroll": "1m", "scroll_id": "FGluY2x1ZGVfY29udGV4dF91dWlkDXF1ZXJ5QW5kRmV0Y2gBFmdVRksxd0VMUUhteEl5SWxCSWxhQWcAAAAAAATk3RZDMFVpdWZUQVNhdXRKaVhpTEdRYkVB"}'
이 요청의 응답에 대해서 error가 발생하는지, 검색결과 문서 리스트가 비어있진 않은지 확인할 필요가 있다.
Bash의 while loop를 이용해서 반복적으로 검색해보자.
page_size=100
while :; do
result=$(curl -s localhost:9200/_search/scroll -H 'Content-Type: application/json' -d '{"scroll": "1m", "scroll\
_id": "'"$scroll_id"'"}')
if echo "$result" | grep -q "error"; then
echo "error in scrolling"
break;
fi
count=$(echo "$result" | jq -r ".hits.hits | length")
if [ "$count" -gt 0 ]; then
echo -n "."
else
echo; echo "end of searching"
break
fi
done
curl -s -X DELETE localhost:9200/test_index
curl -s -X DELETE localhost:9200/_search/scroll -H 'Content-Type: application/json' -d '{ "scroll_id": "FGluY2x1ZGVfY29udGV4dF91dWlkDXF1ZXJ5QW5kRmV0Y2gBFmdVRksxd0VMUUhteEl5SWxCSWxhQWcAAAAAAATk3RZDMFVpdWZUQVNhdXRKaVhpTEdRYkVB" }'
#!/bin/bash
total_count=2000
page_size=100
date
echo; echo "removing..."
if curl -s -X DELETE localhost:9200/test_index > /dev/null; then
echo "success in deleting data"
else
echo "error in deleting data"
exit 1
fi
date
echo; echo "loading..."
i=0
while [ "$i" -lt "$total_count" ]; do
echo -n "."
curl -s -X POST localhost:9200/test_index/_doc -H "Content-Type: application/json" -d '{"num": '"$i"'}' > /dev/null
i=$((i+1))
done
echo
echo "$i"
curl -s localhost:9200/test_index/_refresh
curl -s localhost:9200/test_index/_count
date
echo; echo "removing old scroll cursor..."
scroll_id=$(cat scroll_id.txt)
echo "$scroll_id"
curl -s -X DELETE localhost:9200/_search/scroll -H 'Content-Type: application/json' -d '{ "scroll_id": "'"$scroll_id"'" }' | jq .
echo; echo "searching and getting scroll cursor..."
scroll_id=$(curl -s localhost:9200/test_index/_search\?scroll=1m -H 'Content-Type: application/json' -d '{"size": '"$page_size"', "query": {"match_all": {} } }' | jq -r ._scroll_id)
echo "$scroll_id"
echo "$scroll_id" > scroll_id.txt
echo; echo "searching (with pagination)..."
while :; do
result=$(curl -s localhost:9200/_search/scroll -H 'Content-Type: application/json' -d '{"scroll": "1m", "scroll_id": "'"$scroll_id"'"}')
#echo "$result"
if echo "$result" | grep -q "error"; then
echo "error in scrolling"
break;
fi
count=$(echo "$result" | jq -r ".hits.hits | length")
#echo "$count"
if [ "$count" -gt 0 ]; then
echo -n "."
last_result="$result"
else
echo; echo "end of searching"
break
fi
done
echo
echo "$last_result"
date