기존의 엘라스틱서치로 multi match를 사용하기 위해서 NativeSearchQuery를 썼었다.

하지만 5.0버전 이상부터는 NativeSearchQuery가 Deprecated되었다,
https://docs.spring.io/spring-data/elasticsearch/docs/current/api/deprecated-list.html

NativeQuery
대신 NativeQuery와 Query를 사용하여 multi_match를 구현할 수 있었다.
Query multiMatchQuery = NativeQuery.builder()
.withQuery(
q-> q.multiMatch(MultiMatchQuery.of(builder->
builder
.query(userKeyword)
.fields("title^2", "info", "blind_info", "address")
.boost(1.5f)
.operator(Operator.Or)
.type(TextQueryType.MostFields)
))
).getQuery();
query 에 사용자의 입력을 넣고 검색할 필드로 "title","info","blind_info","address"를 두었다. 그 중 "title"은 ^2로 표시해 중요도를 높였다. boost로 multiMatch의 결과의 비중을 높일 수 있다.
multi_match의 type은 크게 best_fileds (기본값), most_fileds가 있는데 자세한건 다음 링크에서 볼 수 있다.
https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-multi-match-query.html
Multi-match query | Elasticsearch Guide [8.11] | Elastic
The cross_fields type blends field statistics in a complex way that can be hard to interpret. The score combination can even be incorrect, in particular when some documents contain some of the search fields, but not all of them. You should consider the com
www.elastic.co
bool을 사용해서 다른 쿼리들과 함께 should로 묶기 위해 QueryBuilder를 사용했다. 페이징은 NativeQuery를 다시 이용했다.
Query query = QueryBuilders.bool().should(multiMatchQuery).should(keywordMatchQueryList).build()._toQuery();
NativeQuery nativeQuery = NativeQuery.builder()
.withQuery(query)
.withPageable(pageable)
.build();
SearchHits<EDestination> response = elasticsearchOperations.search(nativeQuery, EDestination.class);
실제 쿼리는 다음과 같다.
"Query":{
"bool":{
"should":[
{
"multi_match":{
"boost":1.5,
"fields":["title^2", "info", "blind_info", "address"],
"operator":"or",
"query":"맛집",
"type":"most_fields"
}
}]
}
}
(keywordMathQueryList는 길어서 생략)
NativeQuery
package org.springframework.data.elasticsearch.client.elc;
...
public class NativeQuery extends BaseQuery {
...
public NativeQuery(NativeQueryBuilder builder) {
super(builder);
this.query = builder.getQuery();
this.filter = builder.getFilter();
this.aggregations.putAll(builder.getAggregations());
this.suggester = builder.getSuggester();
this.fieldCollapse = builder.getFieldCollapse();
this.scriptedFields = builder.getScriptedFields();
this.sortOptions = builder.getSortOptions();
this.searchExtensions = builder.getSearchExtensions();
}
public NativeQuery(@Nullable Query query) {
this.query = query;
}
public static NativeQueryBuilder builder() {
return new NativeQueryBuilder();
}
...
}
NativeQuery 클래스는 다음과 같다. 기본적으로 Query를 받거나 NativeQueryBuilder를 사용한다. 이외에도 getQuery(), getFilter() 등 기본적인 getter를 지원한다.
NativeQueryBuilder
package org.springframework.data.elasticsearch.client.elc;
...
public class NativeQueryBuilder extends BaseQueryBuilder<NativeQuery, NativeQueryBuilder> {
...
public NativeQueryBuilder withQuery(Query query) {
Assert.notNull(query, "query must not be null");
this.query = query;
return this;
}
public NativeQueryBuilder withQuery(Function<Query.Builder, ObjectBuilder<Query>> fn) {
Assert.notNull(fn, "fn must not be null");
return withQuery(fn.apply(new Query.Builder()).build());
}
...
}
NativeQueryBuilder도 마찬가지로 filter와 query 등에 대해 getter를 지원한다. 핵심적인 쿼리 부분은 Query를 받거나, withQuery로 람다식을 통해 만들 수 있다. 즉 NativeQuery는 Query의 간편한 제작을 제공한다.
'스프링' 카테고리의 다른 글
| [Spring security] OAuth2Login - JWT 발급 (2) (0) | 2024.03.09 |
|---|---|
| [Spring security] OAuth2Login - Rest API로 커스텀 (1) (0) | 2024.03.09 |