[Spring] Elasticsearch에서의 MultiMatch: 다중 필드에 대한 매칭(feat. Java)- 컴도리돌이
ElasticSearch를 도입하고 데이터를 query DSL 방식으로 조회하는 데 도전하면서, 가장 많이 고민하게 되는 부분 중 하나가 바로 정확한 검색 결과를 어떻게 뽑아낼 것인가라는 문제였어요. 그중에서도 multiMatch는 여러 필드에서 검색어를 한 번에 매칭하게 도와주는 아주 유용한 쿼리랍니다. 이번 포스팅 글에서는 multiMatch 쿼리의 다양한 옵션을 소개하고, Java 코드로 구현하는 법까지 쭉 살펴보려고 합니다. 😊
Java 코드로 MultiMatch 구현하기
multiMatch 쿼리는 여러 필드를 한꺼번에 검색할 때 사용되는 쿼리입니다. 이를 통해 지정한 필드 중 하나라도 매칭되는 문서를 찾아낼 수 있어, 간편하면서도 다채로운 검색 결과를 얻을 수 있어요.
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.MultiMatchQueryBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
// 필드 리스트와 검색어
List<String> fieldList = Arrays.asList("field1", "field2");
String searchInput = "검색어";
// Bool 쿼리 생성
BoolQueryBuilder boolQuery = QueryBuilders.boolQuery()
.must(m -> m.bool(b -> {
b.should(s -> s.bool(b2 -> b2.must(m2 -> m2.multiMatch(mm -> mm
.fields(fieldList)
.query(searchInput)
.type(MultiMatchQueryBuilder.Type.PHRASE)
)).boost(50.0F)));
...
return b;
}));
// 쿼리 빌드
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
sourceBuilder.query(boolQuery);
MultiMatch 쿼리에서는 크게 다섯 가지 옵션을 제공하여 다양한 검색 조건을 설정할 수 있습니다. 각 옵션과 함께 실제 활용 예제를 하나씩 살펴볼게요!
type - 매칭 방식 지정
type 옵션을 통해 쿼리가 매칭되는 방식을 지정할 수 있어요. 아래는 각 타입과 그 의미입니다.
타입설명
best_fields | 기본값, 가장 높은 점수를 가진 필드에서 검색어를 찾음 |
most_fields | 매칭된 모든 필드 점수를 합산하여 검색 결과를 반환 |
cross_fields | 여러 필드를 하나의 필드처럼 취급하여 검색 |
phrase | 정확하게 일치하는 경우에만 매칭 |
phrase_prefix | 접두사 일치를 지원 |
m2 -> m2.multiMatch(
mm -> mm.fields(fieldList)
.query(searchInput)
.type(MultiMatchQueryBuilder.Type.PHRASE)
);
예를 들어, phrase 타입을 설정해 두고 "서울 종로구"를 검색하면 정확히 이 단어 순서로 일치하는 문서만 검색돼요. 😊
fuzziness - 오타 허용
fuzziness 옵션은 유사한 단어나 오타를 허용하고 검색 결과에 포함시킬 때 유용합니다. 오타가 흔한 환경이라면 매우 유용하죠.
예를 들어 "갱상남도 강산시 서장동"을 검색했을 때, fuzziness가 2로 설정되어 있다면 "경상남도 경산시 서상동"으로 유사한 결과를 찾아줄 수 있어요! 😉 아주 유연한 검색 기능이죠?
m2 -> m2.multiMatch(
mm -> mm.fields(fieldList)
.query(searchInput)
.fuzziness("2") // 오타 2글자까지 허용
);
minimum_should_match - 최소 매칭 단어 수 설정
검색어의 최소 단어 수를 설정하는 minimum_should_match는 필드 간에 최소한의 매칭을 요구할 때 사용됩니다. 예를 들어 minimum_should_match("2")를 설정하면 field1과 field2에서 각각 최소 두 단어가 일치해야 결과로 나옵니다.
mn.multiMatch(
mm -> mm.fields(fieldList)
.query(searchInput)
.minimumShouldMatch("2") // 최소 2개의 단어 일치
);
operator - 검색 연산자
검색 조건에 AND 또는 OR을 사용하여 검색의 조건을 강화할 수 있어요. 이 설정을 사용하면 "검색어 1"과 "검색어 2"가 모두 포함된 문서만 결과로 나옵니다.
m2 -> m2.multiMatch(
mm -> mm.fields(fieldList)
.query(searchInput)
.operator(Operator.AND) // AND 연산자
);
고도화된 MultiMatch
고급 검색에서 여러 옵션을 조합하여 더 높은 품질의 결과를 추출할 수 있습니다. 아래는 multiMatch 쿼리의 다양한 옵션을 결합한 예제입니다.
m2 -> m2.multiMatch(
mm -> mm.fields(fieldList)
.query(searchInput)
.type(MultiMatchQueryBuilder.Type.CROSS_FIELDS) // 여러 필드의 내용을 하나로 취급
.fuzziness("AUTO") // 오타 허용 자동 조정
.minimumShouldMatch("70%") // 70% 단어 일치
.operator(Operator.OR) // OR 연산자
);
이 예제에서는 CROSS_FIELDS 타입을 사용해 모든 필드를 하나의 필드처럼 취급하여 검색하고, 오타는 자동으로 조정(AUTO)됩니다. 최소 70%의 단어가 일치할 경우에만 매칭하고, OR 연산자로 검색어의 유연성을 높였어요. 😊
이번 글을 통해 multiMatch 쿼리의 다양한 옵션을 어떻게 활용할 수 있을지 깊이 있게 살펴볼 수 있었습니다. 여러 조건을 유연하게 조합하는 방법을 배움으로써, 앞으로는 더 정교한 검색 조건을 구성할 수 있을 것 같아요. 또한 각 옵션이 사용자의 검색 의도에 맞는 결과를 만들어내는 과정이 정말 흥미로웠습니다. 😃
앞으로는 이 multiMatch 쿼리를 더욱 고도화하여 사용자에게 맞춤형 검색 경험을 제공하고, 상황에 맞는 새로운 조합 방식도 시도해 보고 싶습니다. 이번이 뜻깊은 시간이 되었고, 다음 프로젝트에도 큰 도움이 될 것 같습니다! 😊