Elasticsearch 설치
Elasticsearch 실행을 위해서는 자바1.8 이상의 버전이 설치되어 있어야 합니다.
각 버전별로 필요한 자바 버전은 지원 매트릭스 페이지에서 확인이 가능합니다.
Download Elasticsearch
Mac에서는 brew로 설치가 가능합니다.
brew install elasticsearch
dependency
implementation 'org.springframework.data:spring-data-elasticsearch:4.4.2'
config
@EnableElasticsearchRepositories(basePackages = "dev.demo.searchmodule.repository.search")
@Configuration
public class ElasticsearchConfig {
@Value("${elasticsearch.host}")
private String host;
@Value("${elasticsearch.port}")
private String port;
@Bean(destroyMethod = "close")
public RestHighLevelClient elasticsearchClient() {
ClientConfiguration clientConfiguration = ClientConfiguration.builder()
.connectedTo(host + ":" + port)
.withConnectTimeout(10000)
.withSocketTimeout(10000)
.build();
return RestClients.create(clientConfiguration).rest();
}
}
Spring Elasticsearch Client
spring-data-elasticsearch 4.0.0 이상부터는TransportClient
클래스가 Deprecated 되어RestHighLevelClient
또는ReactiveRestLevelClients
만 사용이 가능합니다.
JPA와 함께 사용한다면
@EnableJpaRepositories
와@EnableElasticsearchRepositories
가 모두 스캔하려하기 때문에 basePackage를 명시해주고,@EnableJpaRepositories
에서는 해당 패키지를 제외해주는 것이 좋습니다.@EnableJpaRepositories(excludeFilters = @ComponentScan.Filter( type = FilterType.ASSIGNABLE_TYPE, classes = BoardSearchRepository.class)) @SpringBootApplication public class ElasticsearchApplication { public static void main(String[] args) { SpringApplication.run(ElasticsearchApplication.class, args); } }
더 많은 정보는 공식문서 Elasticsearch Client에 나와있습니다.
Document
@Getter
@Document(indexName = "gamewood-board")
public class BoardSearch {
@Id
private ObjectId id;
@Field("board_id")
private final Long boardId;
@Field("member_no")
private final String memberNo;
private final String author;
private final String title;
private final String content;
@Builder
@PersistenceConstructor
public BoardSearch(Long boardId, String title, String content, String author) {
this.boardId = boardId;
this.title = title;
this.content = content;
this.author = author;
}
}
@PersistenceConstructor
가 부착된 생성자를 통해 ES에 저장된 Document가 Aggregate로 재구성됩니다.
repository
@Repository
public interface BoardSearchRepository extends ElasticsearchRepository<BoardSearch, String> {
List<BoardSearch> findByAuthor(String author);
}
Spring Data JPA처럼 메서드 이름을 기반으로 CRUD 명령 쿼리를 생성할 수 있고, 복잡한 쿼리를 질의해야한다면 아래와 같이 Operations를 사용하여 쿼리를 작성할 수 있습니다.
@RequiredArgsConstructor
@Repository
public class BoardSearchRepository {
private final ElasticsearchOperations elasticsearchOperations;
public List<BoardSearch> searchBoard(String keyword, List<String> categories, Pageable pageable) {
Query query = new NativeSearchQueryBuilder()
.withQuery(QueryBuilders.boolQuery()
.must(QueryBuilders.queryStringQuery(keyword)
.field(TITLE.value).field(CONTENT.value).field(AUTHOR.value))
).withPageable(pageable).build();
SearchHits<BoardSearch> searchHits = elasticsearchOperations.search(query, BoardSearch.class);
return searchHits.stream()
.map(SearchHit::getContent)
.collect(Collectors.toList());
}
@RequiredArgsConstructor
enum Field {
TITLE("title"),
CONTENT("content"),
AUTHOR("author"),
CATEGORY("category");
private final String value;
}
}
Querybuilder
쿼리는 크게 CriteriaQuery
, StringQuery
, NativeSearchQuery
3가지 방식으로 구현이 가능합니다.
CriteriaQuery
Criteria criteria = new Criteria("price").is(42.0);
Query query = new CriteriaQuery(criteria);
StringQuery
StringQuery
는 JSON String 형태로 쿼리를 받습니다.
Query query = new SearchQuery("{ \"match\": { \"firstname\": { \"query\": \"Jack\" } } } ");
NativeSearchQuery
NativeSearchQuery
는 Aggregate를 사용하거나 복잡한 쿼리를 생성하는데 효과적인 Query 구현체입니다.
Query query = new NativeSearchQueryBuilder()
.addAggregation(terms("lastnames").field("lastname").size(10)) //
.withQuery(QueryBuilders.matchQuery("firstname", firstName))
.build();
Ref.
spring-data-elasticsearch 공식 문서
ES 가이드북
[spring] 스프링 elasticsearch NativeSearchQuery 사용방법
Spring Data Elasticsearch 설정 및 검색 기능 구현