tl;dr
前回からの続きです. 検索ということではありませんが, 念願のシェルスクリプトで scroll API を利用して検索結果の全件を取得してみました.
Abema TV の番組データが登録されている Elasticsearch
「M 愛すべき人がいて」が既にドキュメントとして登録されていることが判ります.
scroll API を利用して検索結果の全レコードを取得する
シェルスクリプト
以下のようなシェルスクリプトを用意しました.
#!/usr/bin/env bash # refer to: https://gist.github.com/cb372/4567f624894706c70e65 # require: jq # 環境に応じて Elasticsearch のエンドポイントとインデックス名を設定する ES_URL='http://localhost:9200' INDEX='abema-channel-*' CMDNAME=$(basename $0) if [ ! $# -eq 1 ]; then echo "Usage: ${CMDNAME} [size]" 1>&2 exit 1 fi SIZE=${1} if [ ${1} -gt 1000 ];then echo 'size cannot be more than 1000.' exit 1 fi # ニーズに応じて関数を実装する function get_title { echo ${1} | jq -r .hits.hits[]._source.title } echo "=== initial request" response=$(curl -H "Content-Type: application/json" -s "${ES_URL}/${INDEX}/_search?scroll=1m&size=${SIZE}" -d @query.json) scroll_id=$(echo ${response} | jq -r ._scroll_id) hits_count=$(echo ${response} | jq -r '.hits.hits | length') hits_so_far=hits_count # echo "Got initial response with ${hits_count} hits and scroll ID ${scroll_id}." # TODO process first page of results here get_title "${response}" i=1 while [ "${hits_count}" != "0" ]; do echo "=== request: $i" response=$(curl -H "Content-Type: application/json" -s ${ES_URL}/_search/scroll -d "{ \"scroll\": \"1m\", \"scroll_id\": \"$scroll_id\" }") scroll_id=$(echo ${response} | jq -r ._scroll_id) hits_count=$(echo ${response} | jq -r '.hits.hits | length') hits_so_far=$((hits_so_far + hits_count)) # echo "Got response with ${hits_count} hits (hits so far: ${hits_so_far}), new scroll ID ${scroll_id}." # TODO process page of results get_title "${response}" # DO NOT REMOVE i=$(expr $i + 1) done echo "Done!" echo "Remove scroll snapshot." curl -XDELETE -H "Content-Type: application/json" "${ES_URL}/_search/scroll" -d " { \"scroll_id\" : \"$scroll_id\" }"
このシェルスクリプトは, 以下のコードを参考にさせて頂きました.
Using the Elasticsearch scroll API · GitHub
シェルスクリプトと一緒に, 以下のような検索クエリ用の JSON ファイル (ファイル名: query.json) を用意します.
{ "query": { "bool": { "must": [ { "query_string": { "query": "title: \"/愛すべき人\"", "analyze_wildcard": true, "default_field": "*" } } ] } } }
動かしてみる
シェルスクリプトに適当な名前 (今回は scroll.sh ) に設定, 実行権限を付与してシェルスクリプトを実行します.
$ chmod 755 scroll.sh $ ./scroll.sh 1 === initial request M ~愛すべき人がいて~ #1~3ダイジェスト+#4 === request: 1 M ~愛すべき人がいて~ #1~3ダイジェスト+#4 === request: 2 【4月新ドラマ】M 愛すべき人がいて #6 === request: 3 M 愛すべき人がいて / #5 これが神様の答えだ! === request: 4 【4月新ドラマ】 #5 これが神様の答えだ! / M 愛すべき人がいて === request: 5 【地上波みながらアベマで語ろう!】M 愛すべき人がいて#5※終了後アベマ独占配信 === request: 6 【地上波みながらアベマで語ろう!】M 愛すべき人がいて#6※終了後アベマ独占配信 === request: 7 Done! Remove scroll snapshot. {"succeeded":true,"num_freed":50}
以上
これまでは, 検索結果を全件取得する際には Python + Elasticsearch ライブラリを用意していましたが, シュッと検索結果が欲しい時に役立ちそうです.