[Tistory] [ElasticSearch]Springboot 매치 쿼리 – @Query, @Mapping, @Setting

원글 페이지 : 바로가기

@Mapping, @Setting https://javas.tistory.com/17 @Setting, @Mapping nori 설정 @ 십질 끝에 정리 – Setting or Mapping 은 최초 index (table) 생성시 적용이 됩니다. – 중간에 끼어 넣기 안됨 , 최초 생성하면서 설정 해줘야함 . – spring data @Document 객체에 @Setting, @Mapping annotation을 통해서 javas.tistory.com https://velog.io/@dktlsk6/Spring-boot-ElasticSearch-%EC%97%B0%EB%8F%99-%ED%95%98%EC%97%AC-%EC%8B%A4%EC%8B%9C%EA%B0%84-%EA%B2%80%EC%83%89-%EC%88%9C%EC%9C%84-%EA%B5%AC%ED%98%84%ED%95%98%EA%B8%B0 Mapping의 경우 입력 값의 매핑 정보(_mapping)을, Setting의 경우 인덱스 설정 정보인 분석기 정보를 집어넣었다. nori 분석기의 경우 이미 elasticsearch에서 받아 적용해놓은 상태임을 유의할 것. 이후 간단한 저장 작업이 동작됨을 확인할 수 있었다. 기존의 JPA와 크게 다르지는 않다. 항상 작업하던 그 규격 @Query 사용 참조 블로그 : https://javas.tistory.com/20 spring jpa , elasticsearch Matches query @Document 를 지정후 interface를 이용해서 쿼리를 하던 중 기본검색은 jpa사용하듯 하면되지만 match를 이용하여 모두 조건이 일치할 떄 데이터가 조회해야되는 이슈가 발생 ex) 화정동 현대, 화정동 힐 javas.tistory.com JPQL(JPA) 처럼 JSON으로 쿼리문을 조합해서 사용할 수 있는 듯 하다. 한번 테스트해보자. JPA처럼 사용할 수 있는 기능이 몇 개 있는 모양이다. Repository 인터페이스: Spring Data Elasticsearch에서는 ElasticsearchCrudRepository나 ElasticsearchRepository 인터페이스를 상속받아 사용한다. 이를 통해 기본 CRUD 작업을 수행할 수 있다. 쿼리 메소드: JPA처럼 메소드 이름으로 쿼리를 정의할 수 있다. 예를 들면, **findByName(String name)**이나 findByNameAndAge(String name, Integer age) 같은 메소드를 정의하면, 해당 필드를 기준으로 검색을 수행한다. @Query 어노테이션: @Query 어노테이션을 사용하면 Elasticsearch의 JSON 쿼리를 직접 작성해서 사용할 수 있다. 이를 통해 매치 쿼리, 텀 쿼리, 불리언 쿼리 등 복잡한 쿼리도 작성 가능하다. Criteria API: Spring Data Elasticsearch는 Criteria API도 제공한다. 이를 사용하면 프로그래밍 방식으로 쿼리를 구성할 수 있다. 이 중 @Query로 직접적으로 확인해보겠다. https://codebeautify.org/jsonminifier Best JSON Minifier, JSON Minify and JSON Compressor Best Online JSON Minifier helps user to Minify, Compress json by removing spaces, lines and tabs. codebeautify.org 해당 사이트에서 JSON 타입으로 쿼리문을 변경할 수 있다. 이를 적용해보자. //?0, ?1 등의 플레이스홀더는 Spring Data의 쿼리 메소드에서 매개변수를 참조할 때 사용하는 방식이다.
//?0은 첫 번째 매개변수, ?1은 두 번째 매개변수를 참조

@Query(“{\”query\”:{\”match\”:{\”accommodation_name\”:\”?0\”}}}”)
List querytest(String name);

//원래 키바나 콘솔에서는 다음과 같았음.
GET test_logstash_accommodations/_search
{
“query”: {
“match”: {
“accommodation_name”: “경상문경청산펜션”
}
}
} 에러 : ‘ElasticsearchException, [type=named_object_not_found_exception, reason=[1:10] unknown field [query]]’ 저렇게 쿼리를 짜도 실제 나가는 값은 :Request body: {“from”:0,”size”:0,”query”:{“wrapper”:{“query”:”eyJxdWVyeSI6eyJtYXRjaCI6eyJhY2NvbW1vZGF0aW9uX25hbWUiOiLqsr3sg4HrrLjqsr3ssq3sgrDtjpzshZgifX19″}},”version”:true,”explain”:false,”track_total_hits”:2147483647} , 이렇게 나간다. Elasticsearch의 wrapper 쿼리는 Base64 인코딩된 쿼리를 감싼 형태로 사용되는데, 여기서는 Spring Data Elasticsearch가 @Query에 제공된 JSON 쿼리를 Base64로 인코딩하고 wrapper 쿼리로 감싸서 Elasticsearch에 전달하는 것으로 보인다. https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-wrapper-query.html Wrapper query | Elasticsearch Guide [8.10] | Elastic A query that accepts any other query as base64 encoded string. response = client.search( body: { query: { wrapper: { query: ‘eyJ0ZXJtIiA6IHsgInVzZXIuaWQiIDogImtpbWNoeSIgfX0=’ } } } ) puts response GET /_search { “query”: { “wrapper”: { “query”: “eyJ0ZXJtIi www.elastic.co 몇시간째 왜 안 되나 고민하는 도중, query를 빼니 동작하는 것을 확인하였다.. 이 부분은 이해가 잘 되지 않지만, 다음과 같은 이유라고 한다. wrapper가 붙는 문제는 Spring Data Elasticsearch가 @Query 애노테이션을 해석할 때 발생하는 것으로 보입니다. 이를 해결하려면 다음과 같은 방법을 시도해 볼 수 있습니다: @Query 애노테이션 대신 메소드 이름을 이용한 쿼리 생성 방법을 사용하면, 내부적으로 wrapper 없이 쿼리를 생성합니다. 다른 방법 Custom Repository 사용하기: Custom Repository를 사용하여 직접 RestHighLevelClient로 쿼리 실행을 수행한다. public interface CustomAccommodationRepository {
List customQuery(String accommodationName);
}

@Repository
public class CustomAccommodationRepositoryImpl implements CustomAccommodationRepository {

private final RestHighLevelClient client;

@Autowired
public CustomAccommodationRepositoryImpl(RestHighLevelClient client) {
this.client = client;
}

@Override
public List customQuery(String accommodationName) {
// RestHighLevelClient를 사용하여 직접 쿼리 실행
// …
}
} NativeSearchQueryBuilder 사용하기: NativeSearchQueryBuilder를 사용하여 Elasticsearch 쿼리를 직접 생성하고 실행한다. @Autowired
private ElasticsearchRestTemplate elasticsearchTemplate;

public List searchWithNativeQuery(String accommodationName) {
NativeSearchQuery searchQuery = new NativeSearchQueryBuilder()
.withQuery(QueryBuilders.matchQuery(“accommodation_name”, accommodationName))
.build();

return elasticsearchTemplate.queryForList(searchQuery, Accommodation.class);
} Wrapper 쿼리를 직접 사용하기: Wrapper 쿼리의 동작을 이용하려면 쿼리를 Base64 인코딩된 문자열로 전환하여 사용할 수 있을 것이다. 이 중 NativeQuery를 사용해보기로 했다. https://juntcom.tistory.com/149 [spring] 스프링 elasticsearch NativeSearchQuery 사용방법 ElasticsearchRepository search 메소드 내부에 NativeSearchQuery 를 넘겨 사용 가능하다. 또는 ElasticsearchTemplate 및 elasticsearchOperations 을 사용할떄도 NativeSearchQuery 를 사용할 수 있다. 쿼리 클래스의 종류로는 C juntcom.tistory.com https://www.baeldung.com/spring-data-elasticsearch-queries

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다