Blog

[Spring][258] Elasticsearch APIs

Author
Summary
Category
Project
Tags
Project
PinOnMain
Favorite
Memory
Memory Date
2023/11/13
Cross Reference Study
Related Media
Related Thought
Related Lessons
tag
기능 구현
날짜
작성자
진행상황
진행 전
태그구분
4 more properties
📌
JPQL 쿼리로 직접 검색 방식 정하기
@Repository public interface ElasticBookSearchRepository extends ElasticsearchRepository<ElasticsearchBook, Long>, ElasticCustomBookSearchRepository { // 이건 개발자가 직접 연산부를 작성하는 방식임 // 제어권이 개발자에 있음 //List<ElasticsearchBook> findByBookNameContains(String keyword); // Elasticsearch API의 쿼리문을 작성해서 변경해보는 방법 // 이건 제어권이 Spring Data Elasticsearch 에 있음 // 쿼리를 SPE가 분석함 //QueryStringQuery - 엘라스틱서치 내장 기본 쿼리 @Query("{\"query_string\": {\"query\": \"?0\"}}") List<ElasticsearchBook> findByQueryStringQuery(String queryString, Pageable pageable); //조건검색(bool) //@Query("{\"bool\": {\"must\": {\"query_string\": {\"query\": \"?0\"}}}}") //List<ElasticsearchBook> findByQueryStringQuery(String queryString, Pageable pageable); /* must: [필드] AND [컬럼] = [조건] must_not: [필드] AND [컬럼] != [조건] should: [필드] OR [컬럼] = [조건] filter: [필드] [컬럼] IN ( [조건] ) */ }
Java
복사
아래 쿼리를 @Query 어노테이션을 통해서 작성하여 검색의 방식을 변경 할 수 있다. 기존 직접 내부 로직을 구성하는 방식과 다르게, 마치 JPQL을 사용하는것 처럼 쿼리문을 작성 할 수 있다. 그럼 마찬가지로 쿼리문이 컴파일 단계에서 검사되지 않는 단점이 있을 것으로 보여진다.
📌
QueryDSL로 구현해보기
build.gradle 의존성 추가
dependencies { implementation 'com.querydsl:querydsl-apt:4.x.x' implementation 'com.querydsl:querydsl-elasticsearch:4.x.x' }
Java
복사
QueryDSL 플러그인 및 태스크 설정
plugins { id "com.ewerk.gradle.plugins.querydsl" version "1.0.10" } querydsl { jpa = false querydslSourcesDir = 'src/main/generated' } sourceSets { main { java { srcDir 'src/main/generated' } } } configurations { querydsl.extendsFrom compileClasspath } compileQuerydsl { options.annotationProcessorPath = configurations.querydsl }
Java
복사
ElasticBookRepository를 상속받은 ElasticBookSearchRepositoryImpl.java 구현체에서 다음처럼 구현한다. Q객체를 통해서 쿼리팩토리를 통해 쿼리를 메소드형태로 작성하게 된다. 이러면 컴파일 단계에서 개발자의 오류를 찾을 수 있다.
import com.querydsl.core.types.dsl.StringPath; import com.querydsl.elasticsearch.ElasticsearchQuery; import com.querydsl.elasticsearch.ElasticsearchQueryFactory; public class ElasticBookSearchRepositoryImpl { private final ElasticsearchQueryFactory queryFactory; public ElasticBookSearchRepositoryImpl(ElasticsearchQueryFactory queryFactory) { this.queryFactory = queryFactory; } public ElasticsearchQuery<ElasticsearchBook> findByQueryStringQuery(String queryString, Pageable pageable) { QElasticsearchBook elasticsearchBook = QElasticsearchBook.elasticsearchBook; StringPath bookName = elasticsearchBook.bookName; return queryFactory .selectFrom(elasticsearchBook) .where(bookName.contains(queryString)) .offset(pageable.getOffset()) .limit(pageable.getPageSize()); } }
Java
복사
아래는 JPQL로 직접 쿼리를 보낼 때의 각 검색 API이다.

1. 검색API Template

{ "size": "[페이징]몇개의 결과를 반환할지 결정한다(default: 10)", "from": "[페이징]어느 위치부터 반환할지 결정한다.(defalut: 0)", "timeout": "제한시간을 설정하여 제한시간까지 조회된 문서만 조회한다.(default: 무한대)", "_source": { // 특정필드만 결과로 반환받고 싶을때 정의한다}, "sort": { // 특정필드를 기준으로 정렬할지 정의한다}, "query": { /* * [전문검색] * 검색될 조건을 정의한다. * 분석기에 의해 분석. */}, "filter": { /* * [조건검색] * 검색 결과 중 특정한 값을 다시 보여준다 * 결과 내에서 재검색 때 사용하는 기능 중 하나다. * 다만 필터를 사용하게 되면 자동으로 score 값이 정렬되지 않는다. * (_score 정렬을 추가하면 가능하다.) */}, "aggs": { // 통계 또는 집계데이터 사용시 정의한다.} }
JSON
복사

2. 검색 파라메터

2.1 Multi Index검색

# 특정인덱스 정의 POST [인덱스1],[인덱스2]/_search # *(와일드카드) 사용 POST [인덱스명]*/_search
Shell
복사
문법
연산자
lt
<
gt
>
lte
<=
gte
>=
POST [인덱스]/_search { "query": { "range": { "필드명": { "gte": "2016",// >= 2016"lte": "2017"// <= 2017} } } }
JSON
복사

2.3 operator

•
AND조회
POST [인덱스]/_search { "query": { "match": { "필드명": { "query": "자전차왕 엄복동", "operator": "and"} } } } /* OR연산 결과 자전차왕 엄복동 자전차왕 홍길동 오토바이왕 엄복동 .... AND연산 결과 자전차왕 엄복동 자전차왕 엄복동 김복동 ... */
JSON
복사

2.4 minimum_should_match

•
매치 최소개수 지정

2.5 boost

•
특정필드에 가중치 부여하여 score을 높이고 상위에 노출하도록 함

3. 문자열 검색

match와 term의 차이

query
필드 타입
설명
match
text
쿼리를 수행하기전에 분석기를 통해 텍스트르 분석한 후 검색을 수행. text 데이터타입을 검색할때 match를 사용.
term
keyword
별도의 분석작업을 수행하지않고 입력된 텍스트가 존재하는 문서를 찾음. keyword 데이터타입을 검색할때 term를 사용.
query_string
-
엘라스틱서치에 내장된 쿼리분석기로 검색.

3.1 match

3.1.1 match_all

•
색인된 모든문서 조회
POST [인덱스]/_search { "query": { "match_all": {} } }
JSON
복사

3.1.2 match / multi_match

•
문장을 형태소 분석을 통해 텀으로 분리 후 텀으로 검색질의 수행.
•
검색어가 분석되야 할 경우 사용한다.
POST [인덱스]/_search { "query": { "match": { "[필드]": "[검색할 키워드]"} } } POST [인덱스]/_search { "query": { "multi_match": { "query": "[검색할 키워드]", "fields": ["[필드1]", "[필드2]"] } } }
JSON
복사

3.2 term

•
정확히 매칭되지않거나, 대소문자가 다른경우 조회되지 않음.
POST [인덱스]/_search { "query": { "term": { "[필드]": "[검색할 키워드]"} } }
JSON
복사

3.3 query_string

•
엘라스틱서치에 기본적으로 내장된 쿼리분석기로 검색
// 전체검색 POST [인덱스]/_search { "query": { "query_string": { "query": "[검색할 키워드]"} } } // 필드검색 POST [인덱스]/_search { "query": { "query_string": { "default_field": "[필드명]", "query": "[검색할 키워드]"} } }
JSON
복사

4. 조건검색

4.1 bool

•
AND, OR, IN 조건을 설정한다.
ElasticSearch
SQL
must: [필드]
AND [컬럼] = [조건]
must_not: [필드]
AND [컬럼] != [조건]
should: [필드]
OR [컬럼] = [조건]
filter: [필드]
[컬럼] IN ( [조건] )
조건 : 장르 = '코미디' AND 국가 = '한국' AND 타입 != '단편' POST [인덱스]/_search { "query": { "bool": { "must": [ { "term": { "장르": "코미디"} }, { "match": { "국가": "한국"} } ], "must_not": [ { "match": { "타입": "단편"} } ] } } }
JSON
복사

5. 그외..

5.1 Prefix Query

•
접두어가 있는 문서를 검색하고자 할때

5.2 Exists Query

•
실제 값이 존재하는 문서만 찾고싶을때.

5.3 Wildcard Query

•
와일드카드와 일치하는 구문을 찾는다.

5.4 Nested Query

•
부모자식 관계 형태(Object)의 데이터타입인 Nested타입 필드 검색할때 사용.

5.5 Multi Search API

•
여러건의 검색을 한번에 요청할때
POST _msearch {"index" : "[인덱스1]"} { "query" : { // 조건}, "from": 0, "size": 10} {"index" : "[인덱스2]"} { "query" : { // 조건}, "from": 0, "size": 10}
JSON
복사

5.6 Count API

•
문서 개수 조회
POST [인덱스]/_count { "query" : { // 조건} }
JSON
복사

5.7 Explain API (_score)

•
_score값이 어떻게 계산된것인지 확인하고싶을때 사용.

5.8 Profile API (튜닝/디버깅)

•
쿼리에 대한 상세한 수행계획과 수행계획별 수행된 시간 조회.