Elasticsearch를 사용하다 보면, 하나의 키워드를 여러 필드에 매칭하여 검색해야 하는 경우가 있습니다. 보통 fields를 사용하여 여러 필드를 배열에 넣고, query 값에 검색어를 입력해 조회하곤 하죠. 예를 들어 아래와 같은 쿼리를 사용해 보신 적 있을 겁니다:
{
"query": {
"bool": {
"must": [
{
"multi_match": {
"query": "경기도 성남시 분당구",
"fields": ["addr", "jibun", "road"]
}
}
]
}
}
}
이 쿼리는 지정된 필드들 중에서 키워드와 매칭되는 데이터를 찾아줍니다. 그런데 여기서 궁금한 점이 하나 생깁니다. 어떤 필드가 검색 결과와 매칭되었는지 알고 싶을 때는 어떻게 해야 할까요? 🤔
예를 들어 사용자가 검색 창에 특정 키워드를 입력하면 연관 검색어 리스트가 표시됩니다. 하지만 이 리스트가 실제로 어떤 필드에서 검색되었는지는 사용자 입장에서는 알 수 없습니다. 그렇다면 Elasticsearch에서 이를 확인하려면 어떻게 해야 할까요?
Highlight로 필드 매칭 확인하기
하이라이팅은 문서 검색 결과에 사용자가 입력한 검색어를 강조하는 기능으로, 해당 기능을 통해 사용자가 입력한 검색어가 어디에 일치되는지는 쉽게 눈으로 확인할 수 있어요. 즉 사용자의 편의를 위한 기능 중 한 가지라 보면 됩니다.
다음과 같은 데이터를 가지고 있다고 가정해 봅시다:
"_source" : {
"jibun" : "경상북도 경주시 용강동 757 삼성",
"road" : "경상북도 경주시 산업로 4465 (용강동)",
"addr" : "경상북도 경주시 용강동 757번지"
},
위 데이터에서 특정 키워드 "삼성"을 검색한다고 가정해 보겠습니다. 이제 매칭된 필드와 내용을 확인할 수 있는 highlight 옵션을 추가해 보겠습니다. 그리고 아래와 같은 쿼리를 실행합니다:
{
"query": {
"bool": {
"must": [
{
"multi_match": {
"query": "삼성",
"fields": ["addr", "jibun", "road"]
}
}
]
}
}
,"highlight": {
"fields": {
"addr": {},
"jibun": {},
"road": {}
}
}
, "_source": ["addr", "jibun", "road"]
}
이 쿼리는 highlight 섹션을 추가하여 어떤 필드에서 검색어가 매칭되었는지 표시합니다. 결과는 다음과 같이 나옵니다:
{
...
"_score" : 11.335677,
"_source" : {
"jibun" : "경상북도 경주시 용강동 757 삼성",
"road" : "경상북도 경주시 산업로 4465 (용강동)",
"addr" : "경상북도 경주시 용강동 757번지"
},
"highlight" : {
"jibun" : [
"경상북도 경주시 용강동 757 <em>삼성</em>"
]
}
},
...
결과를 보면 highlight 섹션에 검색 키워드가 매칭된 필드와 강조된 내용이 나타납니다. 위의 예에서는 jibun 필드에서 검색어 "삼성"이 매칭되었고, <em> 삼성 </em><em> 삼성 </em>으로 강조 표시되었습니다. 크게 어렵지 않죠? 위처럼 쿼리를 날리게 되면 결과로 highlight가 나오는 걸 볼 수 있어요. 화면에 뿌려줄 때에는 hightlight 부분을 검색결과 링크로 뿌려주어도 될 것 같네요. 그렇지만 em 태그가 아닌 다른 태그로 하이라이팅을 하고 싶을 수 도 있겠죠? 그럴 때에는 몇 개의 옵션을 더 추가하면 됩니다.
,"highlight": {
"pre_tags":["<highlight>"],
"post_tags":["</highlight>"],
"fields": {
"addr_road": {},
"addr_jibun": {},
"bld_nm": {}
}
}
pre_tags, post_tags 옵션을 주어 하이라이팅 할 단어에 태그를 지정해 줄 수 있어요.
결과 값으로 다음과 같이 조회됩니다.
"highlight" : {
"jibun" : [
"경상북도 경주시 용강동 757 <highlight>삼성</highlight>"
]
}
Java 코드로 구현하기
Elasticsearch를 Java 코드로 연동할 때도 highlight는 간단히 설정할 수 있습니다. 다음은 Java 클라이언트를 사용해 highlight를 활용하는 코드 예제입니다:
SearchResponse<Map<String, Object>> response = elasticsearchClient.search(
s -> s.index("addr_index")
.query(q -> q.bool(b -> b.must(
m -> m.multiMatch(
mm -> mm.fields(Arrays.asList("addr", "jibun", "road"))
.query(searchInput)
)
)
))
.highlight(h -> h.fields("addr", hf -> hf)
.fields("jibun", hf -> hf)
.fields("road", hf -> hf)
)
, (Type) Map.class);
Elasticsearch의 highlight는 검색 결과에 필드 매칭과 강조된 내용을 표시하는 데 매우 유용합니다.
이를 활용하면 검색의 신뢰성과 사용자 경험을 모두 향상할 수 있습니다.
'DevOps > Elastic Stack' 카테고리의 다른 글
[Elasticsearch] Cardinality 집계, 유니크한 값의 수 - 컴도리돌이 (2) | 2024.12.23 |
---|---|
[Elasticsearch] Elasticsearch 집계하기, 버킷 집계(Bucket Aggregation)과 메트릭 집계(Metric Aggregation) (Feat. Java) - 컴도리돌이 (1) | 2024.12.21 |
[Elasticsearch] 성능 향상을 위한 doc_values 사용법: 메모리 효율 향상시키기 - 컴도리돌이 (3) | 2024.11.09 |
[Elasticsearch] 성능 개선을 위한 코드 비교 및 분석 - 컴도리돌이 (4) | 2024.11.08 |
[Elasticsearch] wildcard 쿼리에 대해 제대로 이해하기 - 컴도리돌이 (0) | 2024.11.07 |