개발놀이터
Elasticsearch 스프링에서 사용하기 본문
이번 포스팅에선 이제 제가 공부하는 스프링에서 사용해봐야죠. 우리는 앞선 포스팅에서 Elassticsearch의 전반적인 내용과 CRUD를 해봤습니다.
스프링에선 Elasticsearch를 어떻게 사용하고있을까요?
한번 알아보죠!
스프링에서 Elasticsearch 사용하기
// elasticsearch
implementation 'org.springframework.boot:spring-boot-starter-data-elasticsearch'
implementation 'org.elasticsearch.client:elasticsearch-rest-high-level-client'
우선 의존성을 추가해줍니다.
ElasticsearchConfig.java
package com.hello.capston.elasticsearch.config;
import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class ElasticsearchConfig {
@Value("${spring.data.elasticsearch.host}")
private String host;
@Value("${spring.data.elasticsearch.port}")
private int port;
@Bean(destroyMethod = "close")
public RestHighLevelClient client() {
RestClientBuilder builder = RestClient.builder(new HttpHost(host, port));
RestHighLevelClient client = new RestHighLevelClient(builder);
return client;
}
}
Elasticsearch에서 사용될 Configuration 클래스입니다.
Elasticsearch에선 high-level 과 low-level을 지원하는데 둘의 차이는 low-level을 사용하기 쉽게 추상화한 것이 바로 high-level입니다. 둘의 성능적인 차이는 잘 모르겠지만 조금 변태같은 취미가 있으신 분들은 low-level을 추천드립니다.
또한 저는 spring-data-elasticsearch를 사용하지 않았습니다. 사용방법은 spring-data-jpa와 비슷하다고 합니다.
ElasticItem.java
package com.hello.capston.elasticsearch.entity;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.springframework.data.annotation.Id;
import org.springframework.data.annotation.PersistenceConstructor;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;
@Document(indexName = "item")
@Getter
@NoArgsConstructor
public class ElasticItem {
@Id
private String id;
@Field(type = FieldType.Text)
private String view_name;
@Field(type = FieldType.Text)
private String item_url;
@Field(type = FieldType.Text)
private String item_name;
@Field(type = FieldType.Integer)
private int price;
@PersistenceConstructor
public ElasticItem(String view_name, String item_url, String item_name, int price) {
this.view_name = view_name;
this.item_url = item_url;
this.item_name = item_name;
this.price = price;
}
}
이 Document 클래스가 은근히 중요합니다. 클래스 레벨에선 @Document 를 이용해 해당 클래스가 Elasticsearch의 Document와 대응되는 클래스라는 것을 명시합니다.
그리고 각각의 필드들은 실제 Elasticsearch에 저장된 필드명을 적어야하고
가장 중요한 @PersistenceConstructor 를 이용해 실제 Elasticsearch의 객체와 우리 @Document 클래스를 매핑해줍니다.
주의해야하는 점은 생성자에 파라미터로 들어간 내용으로 매핑하기 때문에 맘대로 바꾸시면 안됩니다. Elasticsearch에 있는 필드명과 동일하게 작성해주셔야 에러가 안뜹니다.
package com.hello.capston.elasticsearch.service;
import com.hello.capston.elasticsearch.entity.ElasticItem;
import lombok.RequiredArgsConstructor;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.stream.Collectors;
@Service
@RequiredArgsConstructor
public class ElasticsearchService {
private final ElasticsearchRestTemplate template;
public List<ElasticItem> search(String name) {
QueryBuilder queryBuilder = QueryBuilders.matchQuery("viewName", name);
SearchHits<ElasticItem> searchHits = template.search(new NativeSearchQueryBuilder()
.withQuery(queryBuilder)
.withPageable(PageRequest.of(0, 10))
.build(), ElasticItem.class);
List<ElasticItem> collect = searchHits.get().map(SearchHit::getContent).collect(Collectors.toList());
return collect;
}
}
직접적으로 검색을 도와줄 Service클래스입니다. ElasticsearchRestTemplate을 이용해 쿼리문을 만들어서 HTTP로 쏴주는 역할을 합니다.
실제로 디버깅을 해보시면 쿼리문을 자동으로 생성해주는 역할을 하고 있다는 것을 알 수 있습니다.
이제 이걸 그대로 컨트롤러에서 가져다 쓰면 됩니다.
컨트롤러에서 사용하는건 너무 간단해서 포스팅에 작성하지는 않겠습니다.
마치며
이렇게 스프링에서 Elasticsearch를 사용하는 방법에 대해서 알아봤습니다.
스프링에서 사용하는 방법은 그렇게 어렵진 않았지만 이 방법을 찾기까지 수많은 삽질이 있었습니다. 뭐 별에별 방법들이 있었는데 저는 이 방법이 가장 깔끔하고 간단하면서 유지보수 하기도 쉬운 것 같습니다.
여기까지 긴 글 읽어주셔서 감사합니다. 오늘도 즐거운 하루 되세요~
'CS 지식 > 데이터베이스' 카테고리의 다른 글
MySQL 에서 MySQL로 DBeaver 이용해서 데이터 마이그레이션 진행하기 (0) | 2023.06.06 |
---|---|
Elasticsearch 에 MySQL 데이터 동기화하기 (데이터 마이그레이션) (0) | 2023.05.26 |
Elasticsearch CRUD 해보기 (0) | 2023.05.26 |
Redis 로 캐싱 구현하기 ver.2 (Low Level 코딩) (0) | 2023.05.15 |
Redis를 이용해 세션 구현하기 (with Spring) (0) | 2023.05.03 |