Elasticsearch でつまづいた話 (3)
今回のテーマはページング取得。
Query したときの件数
RDB の発想だと SQL select * from table
したら全件取得されるのが当然だが Elasticsearch だと何も指定しなければ 10 件までしか取得されない。
size を指定するとこれを大きくできる。
{ "size" : 100, "query" : { ... } }
だが、この size にも上限がある。デフォルトだと 10,000 件だ ( _settings の index.max_result_window
で定義されている) 。
作法としては Scroll API というのを使う。これは、ある時点でのスナップショットを保存して、取得しきれなかった分を辿っていくというものだ。
( From/Size でやろうとすると追加/削除があった場合に過不足が発生するので良くない)
クエリ文字列として scroll=hoge
を渡す。 hoge
は 1m
など、スナップショットを保持する期間を指定する。
curl -XGET '[host]/_search?scroll=1m' -d ' { "size" : 100, "query" : { ... } }'
レスポンスは以下のようになる。
{ "_scroll_id" : "hogehoge", "hits" : { ... } }
_scroll_id
があるということは、取得しきれなかった分があることを意味する。続きを取得するには、以下のリクエストを送る。このときクエリを指定する必要はない。
curl -XGET '[host]/_search?scroll' -d ' { "scroll_id" : "hogehoge" }'
このレスポンスにも続きがあれば新たな _scroll_id
が返ってくるので、それを使って再び叩くことになる。
取得が完了したら、 DELETE
でスナップショットを削除すると行儀がいい。
Aggregation 時もページングが必要になる場合があるが、その際はまたちょっと違った API を使うことになる。その話はまた今度。