사내 프로젝트로 검색엔진 구축 진행 중에 있다.
검색시 검색결과의 순서를 조정하는 방법을 고심하던 중 python elasticsearch client를 사용하여 검색결과의 순위를 상위로 고정해보자.
검색어가 Boost_index(검색 순위 상위 고정 할 정보를 담은 인덱스)의 Doc_id와 같을 때, 해당하는 doc에 존재하는 boost_id의 문서를 해당 검색어 입력 시 가중치를 주어 상위로 결과를 노출 시킨다.
테스트 검색 인덱스 : doc_index_test
부스팅 할 문서의 정보가 들어있는 인덱스 : boost_index
queryDSL과 그에 맞는 코드를 같이 첨부하였음
예시로 "기능"이라는 검색어를 기준으로 해보자. doc_index_test에 기능 검색시 5개 결과가 나온다.
GET boost_index/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"_id": "기능"
}
}
]
}
},
"size":100
}
from fastapi import APIRouter, HTTPException, Request
from engine.elasticsearch_client import es
from typing import Optional, List, Any
from engine.elasticsearch_query import get_search_id, get_search_should_overhead
from engine.elasticsearch_result import handle_search_results
import re
router = APIRouter()
# 카테고리별 인덱스 매핑
CATEGORY_INDEX_MAP = {
"doc": "doc_index_test"
}
BOOST_INDEX_MAP2 = {
"doc": "boost_index"
}
#boost_index에 검색어가 포함된 doc id에 있는지 확인하는 함수
def search_boostkey_id(
request: Request,
query: str,
category: Optional[str] = "total"
):
body = get_search_id(query,size=100)
if category == "total":
for cat, index_pattern in BOOST_INDEX_MAP2.items():
response = es.search(index=index_pattern, body=body)
results = handle_search_results(response)
print("::results::",results)
print("::response::",response)
return results
else:
index_to_search = CATEGORY_INDEX_MAP.get(category, "farm_test_doc_index") # 기본값 설정
response = es.search(index=index_to_search, body=body)
results = handle_search_results(response)
return results
GET doc_index_test/_search
{
"query": {
"bool": {
"must": [
{
"query_string": {
"query": "기능"
}
}
],
"should": [
{
"term": {
"_id": {
"value": "kIZt-YoB6MtPcT2qgxgS",
"boost": 1000
}
}
},
{
"term": {
"_id": {
"value": "k4Zt-YoB6MtPcT2qiBh7",
"boost": 1000
}
}
}
]
}
}
}
@router.get('/search/doc/overhead')
async def search_overhead(query:str, page: int = 1, size: int = 10):
#주어진 데이터
data = search_boostkey_id(Request,query)
print("::data::",data)
# documents에서 keyword와 입력한 단어가 일치하는 경우 boost_id를 추출
boost_ids = []
doc_keywords = []
# documents에서 keyword 추출 (keyword= _id)
for document in data['documents']:
keyword = document.get('keyword')
# keyword가 검색어와 일치한다면
if keyword == query:
boost_list = document.get('boost', [])
print("단어일치할때 부스트리스트:",boost_list)
# boost_list가 비어 있지 않다면
if boost_list:
# boost_id를 for문으로 추출하여 리스트에 추가
boost_ids.extend(boost['boost_id'] for boost in boost_list)
body = get_search_should_overhead(query,boost_ids,size=size)
print("::body::",body)
all_results = {}
for cat, index_pattern in CATEGORY_INDEX_MAP.items():
response = es.search(index=index_pattern, body=body)
results = handle_search_results(response)
all_results[cat]={
**results['meta'],
'page': page,
'size': size,
'documents': results['documents']
}
return all_results