ページ付け
アプリケーションが非常に多数の結果を処理することは、多くの場合非現実的です。このため、API と Web サービスではページ区切りコントロールを使用して、アプリケーションが結果を小さなチャンクまたはページで要求できるようにします。
デフォルトでは、Elasticsearch は 10 件を超える結果を返さないことに気付いたかもしれません。オプションのsizeパラメータを検索リクエストに指定すると、この最大値を変更できます。次の例では、最大 5 件の検索結果を返すように要求しています。
results = es.search(
query={
'multi_match': {
'query': query,
'fields': ['name', 'summary', 'content'],
}
}, size=5
)結果の追加ページにアクセスするには、 from_パラメータを使用します。これは、完全な結果リストのどこから開始するかを示します ( fromは Python の予約キーワードであるため、 from_が使用されます)。
次の例では、2 ページ目の 5 件の結果を取得します。
results = es.search(
query={
'multi_match': {
'query': query,
'fields': ['name', 'summary', 'content'],
}
}, size=5, from_=5
)app.pyのhandle_search()エンドポイントにsizeとfrom_を組み込みましょう。
@app.post('/')
def handle_search():
query = request.form.get('query', '')
from_ = request.form.get('from_', type=int, default=0)
results = es.search(
query={
'multi_match': {
'query': query,
'fields': ['name', 'summary', 'content'],
}
}, size=5, from_=from_
)
return render_template('index.html', results=results['hits']['hits'],
query=query, from_=from_,
total=results['hits']['total']['value'])ここで、ページ サイズは 5 にハードコードされています (任意の他の数値を自由に使用できます)。from_引数は、送信されたフォームの追加フィールドとして指定されると想定されていますが、このフィールドはオプションと見なされ、存在しない場合はデフォルトで 0 になります。
index.htmlで使用できる検索フォームにはfrom_フィールドがないため、通常の検索は常に最初の結果から開始されます。テンプレートには、表示される結果の範囲と合計に関する情報が表示されます。テンプレート式を使用してこれを実行する方法は次のとおりです。
<div class="col-sm-auto my-auto">
Showing results {{ from_ + 1 }}-{{ from_ + results|length }} out of {{ total }}.
</div>テンプレートには、結果リスト内を前方または後方に移動するためのページ区切りボタンを表示するロジックも含まれています。「前の結果」ボタンの実装は次のとおりです。
{% if from_ > 0 %}
<div class="col-sm-auto my-auto">
<a href="javascript:history.back(1)" class="btn btn-primary">← Previous page</a>
</div>
{% endif %}ご覧のとおり、「前のページ」ボタンは、 from_が 0 より大きい場合にのみページにレンダリングされます。このボタンの実装では、ブラウザの履歴 API を使用して 1 ページ戻ります。
「次のページ」ボタンの実装はさらに興味深いものになっています。
{% if from_ + results|length < total %}
<div class="col-sm-auto my-auto">
<form method="POST">
<input type="hidden" name="query" value="{{ query }}">
<input type="hidden" name="from_" value="{{ from_ + results|length }}">
<button type="submit" class="btn btn-primary">Next page →</button>
</form>
</div>
{% endif %}このボタンは実際にはスタンドアロンのボタンではなく、ボタンに加えて 2 つの隠しフィールドを持つ完全なフォームです。このフォームはメインの検索フォームに似ていますが、次の結果ページを指すように調整されたオプションのfrom_フィールドが含まれています。このボタンをクリックすると、Flask アプリケーションはこの代替フォームからの検索要求を受け取ります。この要求では、同じテキスト クエリが使用されますが、値はゼロ以外のfrom_になります。
この小さくて巧妙なページ区切りの実装により、複数の結果ページをナビゲートできるようになります。