分页
对于应用程序来说,处理大量结果往往是不切实际的。因此,应用程序接口和网络服务使用分页控件,允许应用程序以小块或小页的形式请求结果。
您可能已经注意到,Elasticsearch 默认返回的结果不超过 10 个。可在搜索请求中提供可选的size 参数,以更改这一最大值。下面的示例要求最多返回 5 个搜索结果:
results = es.search(
query={
'multi_match': {
'query': query,
'fields': ['name', 'summary', 'content'],
}
}, size=5
)要访问更多的结果页面,需要使用from_ 参数,该参数指示从完整结果列表的哪个页面开始(由于from 是 Python 的保留关键字,所以使用from_ )。
下一个示例将检索第二页的 5 个结果:
results = es.search(
query={
'multi_match': {
'query': query,
'fields': ['name', 'summary', 'content'],
}
}, size=5, from_=5
)让我们将size 和from_ 并入app.py 中的handle_search() 端点:
@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_ 大于零时,才会显示"上一页" 按钮。该按钮的实现使用了浏览器的历史 API 来返回一页。
"下一页" 按钮的实现要有趣得多:
{% 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 %}这个按钮实际上不是一个独立的按钮,而是一个完整的表单,除了按钮外,还有两个隐藏字段。该表单与主搜索表单类似,但包括可选的from_ 字段,并调整为指向下一页结果。点击该按钮后,Flask 应用程序将从该备用表单接收搜索请求,该表单使用相同的文本查询,但from_ 值不为零。
有了这个小巧巧妙的分页功能,您就可以浏览多页结果了。