페이지 매김

애플리케이션이 매우 많은 수의 결과를 처리하는 것은 비현실적인 경우가 많습니다. 이러한 이유로 API와 웹 서비스는 페이지 매김 컨트롤을 사용하여 애플리케이션이 작은 청크 또는 페이지 단위로 결과를 요청할 수 있도록 합니다.

Elasticsearch가 기본적으로 10개 이상의 결과를 반환하지 않는다는 것을 눈치채셨을 것입니다. 검색 요청에 size 매개변수(선택 사항)를 지정하여 이 최대값을 변경할 수 있습니다. 다음 예에서는 최대 5개의 검색 결과를 반환하도록 요청합니다:

results = es.search(
    query={
        'multi_match': {
            'query': query,
            'fields': ['name', 'summary', 'content'],
        }
    }, size=5
)

결과의 추가 페이지에 액세스하려면 전체 결과 목록에서 시작할 위치를 나타내는 from_ 매개변수가 사용됩니다( from 은 파이썬에서 예약된 키워드이므로 from_ 사용).

다음 예는 5개의 결과 중 두 번째 페이지를 검색합니다:

results = es.search(
    query={
        'multi_match': {
            'query': query,
            'fields': ['name', 'summary', 'content'],
        }
    }, size=5, from_=5
)

app.py의 handle_search() 엔드포인트에 sizefrom_ 을 통합해 보겠습니다:

@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를 사용하여 한 페이지 뒤로 이동합니다.

"다음 페이지" 버튼은 훨씬 더 흥미로운 방식으로 구현되어 있습니다:

{% 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_ 필드가 옵션으로 포함되어 있습니다. 이 버튼을 클릭하면 플라스크 애플리케이션은 동일한 텍스트 쿼리를 사용하지만 0이 아닌 from_ 값을 사용하는 이 대체 양식에서 검색 요청을 받습니다.

이 작고 영리한 페이지 매김 구현을 통해 여러 페이지의 결과를 탐색할 수 있습니다.

최첨단 검색 환경을 구축할 준비가 되셨나요?

충분히 고급화된 검색은 한 사람의 노력만으로는 달성할 수 없습니다. Elasticsearch는 여러분과 마찬가지로 검색에 대한 열정을 가진 데이터 과학자, ML 운영팀, 엔지니어 등 많은 사람들이 지원합니다. 서로 연결하고 협력하여 원하는 결과를 얻을 수 있는 마법 같은 검색 환경을 구축해 보세요.

직접 사용해 보세요