시맨틱 쿼리

이제 인덱스에 ELSER 임베딩이 탑재되었으므로 app.py의 handle_search() 함수를 변경하여 이러한 임베딩을 검색할 수 있습니다. 지금은 ELSER를 통해서만 검색하는 방법을 보여드리며, 나중에 이전 검색 방법을 다시 통합하여 통합 솔루션을 만들 예정입니다.

검색 시 ELSER 추론을 사용하려면 text_expansion 쿼리 유형이 사용됩니다. 아래에서 이 쿼리로 업데이트된 handle_search() 함수를 확인할 수 있습니다:

@app.post('/')
def handle_search():
    query = request.form.get('query', '')
    filters, parsed_query = extract_filters(query)
    from_ = request.form.get('from_', type=int, default=0)

    results = es.search(
        query={
            'text_expansion': {
                'elser_embedding': {
                    'model_id': '.elser_model_2',
                    'model_text': parsed_query,
                }
            },
        },
        size=5,
        from_=from_,
    )
    return render_template('index.html', results=results['hits']['hits'],
                           query=query, from_=from_,
                           total=results['hits']['total']['value'])

text_expansion 쿼리는 검색할 필드의 이름이 포함된 키를 받습니다. 이 키에서 model_id 은 검색에 사용할 모델을 구성하고 model_text 은 검색할 대상을 정의합니다. 이 경우 검색 텍스트에 대한 임베딩을 생성할 필요가 없는데, Elasticsearch가 모델을 관리하고 이를 처리할 수 있기 때문입니다.

위의 handle_search() 버전에서 filters 은 사용되지 않은 채로 남겨져 있으며 집계는 생략되었습니다. 이러한 기능은 전체 텍스트 검색 솔루션에 통합된 것과 동일한 방식으로 다시 추가할 수 있습니다. 아래는 text_expansion 쿼리를 bool.must 섹션 내부로 이동하는 업데이트된 handle_search() 함수로, 이전과 같이 bool.filter 에 필터가 포함되고 집계가 추가되었습니다.

@app.post('/')
def handle_search():
    query = request.form.get('query', '')
    filters, parsed_query = extract_filters(query)
    from_ = request.form.get('from_', type=int, default=0)

    results = es.search(
        query={
            'bool': {
                'must': [
                    {
                        'text_expansion': {
                            'elser_embedding': {
                                'model_id': '.elser_model_2',
                                'model_text': parsed_query,
                            }
                        },
                    }
                ],
                **filters,
            }
        },
        aggs={
            'category-agg': {
                'terms': {
                    'field': 'category.keyword',
                }
            },
            'year-agg': {
                'date_histogram': {
                    'field': 'updated_at',
                    'calendar_interval': 'year',
                    'format': 'yyyy',
                },
            },
        },
        size=5,
        from_=from_,
    )
    aggs = {
        'Category': {
            bucket['key']: bucket['doc_count']
            for bucket in results['aggregations']['category-agg']['buckets']
        },
        'Year': {
            bucket['key_as_string']: bucket['doc_count']
            for bucket in results['aggregations']['year-agg']['buckets']
            if bucket['doc_count'] > 0
        },
    }
    return render_template('index.html', results=results['hits']['hits'],
                           query=query, from_=from_,
                           total=results['hits']['total']['value'], aggs=aggs)

시간을 들여 다양한 검색을 실험해 보세요. 고밀도 벡터 임베딩과 마찬가지로, 색인된 문서에 정확한 단어가 나타나지 않을 때 ELSER 모델에 의한 검색이 전체 텍스트 검색보다 더 잘 작동한다는 것을 알 수 있습니다.

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

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

직접 사용해 보세요