分页

对于应用程序来说,处理大量结果往往是不切实际的。因此,应用程序接口和网络服务使用分页控件,允许应用程序以小块或小页的形式请求结果。

您可能已经注意到,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
)

让我们将sizefrom_ 并入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_ 值不为零。

有了这个小巧巧妙的分页功能,您就可以浏览多页结果了。

准备好打造最先进的搜索体验了吗?

足够先进的搜索不是一个人的努力就能实现的。Elasticsearch 由数据科学家、ML 操作员、工程师以及更多和您一样对搜索充满热情的人提供支持。让我们联系起来,共同打造神奇的搜索体验,让您获得想要的结果。

亲自试用