Elasticsearch를 Spring Boot에서 작업을 하는 간단한 정리를 해보자.
1. Library 추가
Elasticsearch를 사용하기 위해서는 spring-data-elasticsearch 라이브러리가 추가되어야 한다.
gradle에 추가해보자.
1 2 3 4 5 6 7 | dependencies { implementation 'org.springframework.boot:spring-boot-starter-data-elasticsearch' implementation 'org.springframework.boot:spring-boot-starter-web' testImplementation 'org.springframework.boot:spring-boot-starter-test' compileOnly "org.projectlombok:lombok:1.16.16" } | cs |
spring-data-elasticsearch 버전별로 호환되는 elasticsearch가 상이하니 참고
spring data elasticsearch | elasticsearch |
---|---|
3.2.x | 6.5.0 |
3.1.x | 6.2.2 |
3.0.x | 5.5.0 |
2.1.x | 2.4.0 |
2.0.x | 2.2.0 |
1.3.x | 1.5.2 |
2. Configuration
Elasticsearch에 접속하기 위한 Configuration을 정의해준다.
Elasticsearch 접속을 위해서는 host, port, cluster name이 필요하다. cluster name을 알아야 하는데 docker에 설치 한 경우 여기서 확인하면 된다.
우선 docker exec -it elastic bash로 콘솔에 접속한 후에 elasticsearch.yml에 적혀있는 cluster name을 확인한다.
그리고 application.properties에 설정 내용을 적어준다.
1 2 3 4 | elasticsearch.host=127.0.0.1 elasticsearch.port=9300 elasticsearch.cluster_name=docker-cluster spring.main.allow-bean-definition-overriding=true | cs |
그리고 EnableElasticsearchRepositories 애노테이션을 설정한 Configuration 클래스를 만들어준다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | package com.elasticsearch.study.configuration; import org.springframework.beans.factory.annotation.Value; import org.elasticsearch.client.Client; import org.elasticsearch.client.transport.TransportClient; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.transport.TransportAddress; import org.elasticsearch.transport.client.PreBuiltTransportClient; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.elasticsearch.core.ElasticsearchOperations; import org.springframework.data.elasticsearch.core.ElasticsearchTemplate; import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories; import java.net.InetAddress; /** * Elasticsearch Configuration * * @author wedul * @since 2019-02-09 **/ @EnableElasticsearchRepositories @Configuration public class ElasticConfiguration { @Value("${elasticsearch.host}") private String host; @Value("${elasticsearch.port}") private int port; @Value("${elasticsearch.cluster_name") private String clusterName; @Bean public Client client() throws Exception { Settings settings = Settings.builder().put("cluster.name", clusterName).build(); TransportClient client = new PreBuiltTransportClient(settings); client.addTransportAddress(new TransportAddress(InetAddress.getByName(host), port)); return client; } @Bean public ElasticsearchOperations elasticsearchTemplate() throws Exception { return new ElasticsearchTemplate(client()); } } | cs |
3. DTO 생성
Elasticsearch에서 Document 내용을 담을 DTO를 만들어주고 @Document 애노테이션을 달고 index name과 type을 정의해준다.
@Id 어노테이션이 붙은 필드는 각 Doucument에 붙어있는 _id 값이다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | package com.elasticsearch.study.dto; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import lombok.ToString; import org.springframework.data.annotation.Id; import org.springframework.data.elasticsearch.annotations.Document; /** * studyFor * * @author wedul * @since 2019-02-09 **/ @Data @AllArgsConstructor @NoArgsConstructor @ToString @Builder @Document(indexName = "wedul_play", type = "story") public class WedulPlay { @Id private String id; private String title; private String user; private long startAt; private long endAt; } | cs |
4. Repository
JPA를 사용하면 익숙할 패턴으로 Elasticsearch에서도 ElasticsearchRepository가 존재한다. 사용방법은 JPA와 동일하게 저장할 때는 save, 조회할 때는 find(), findByUser()등으로 사용할 수 있다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | package com.elasticsearch.study.repository; import com.elasticsearch.study.dto.WedulPlay; import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; import org.springframework.stereotype.Repository; /** * study * * @author wedul * @since 2019-02-09 **/ @Repository("wedulPlayRepository") public interface WedulPlayRepository extends ElasticsearchRepository<WedulPlay, String> { WedulPlay findByUser(String user); } | cs |
5. Service
지금 테스트 하는 부분에서는 크게 비즈니스 로직에 들어갈 소스가 없다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | package com.elasticsearch.study.service; import com.elasticsearch.study.dto.WedulPlay; import com.elasticsearch.study.repository.WedulPlayRepository; import com.google.common.collect.Lists; import lombok.AllArgsConstructor; import lombok.NoArgsConstructor; import org.springframework.stereotype.Service; import java.util.List; /** * study * * @author wedul * @since 2019-02-09 **/ @AllArgsConstructor @NoArgsConstructor @Service public class WedulPlayService { private WedulPlayRepository wedulPlayRepository; public void save(WedulPlay play) { wedulPlayRepository.save(play); } public List<WedulPlay> findAll() { return Lists.newArrayList(wedulPlayRepository.findAll()); } public WedulPlay findByUser(String user) { return wedulPlayRepository.findByUser(user); } } | cs |
6. Test 코드
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | package com.elasticsearch.study.wedulplay; import com.elasticsearch.study.dto.WedulPlay; import com.elasticsearch.study.repository.WedulPlayRepository; import com.elasticsearch.study.service.WedulPlayService; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import java.util.List; import org.hamcrest.core.IsNull; import static org.hamcrest.CoreMatchers.*; import static org.junit.Assert.*; /** * wedul play document 조회 * * @author wedul * @since 2019-02-09 **/ @RunWith(SpringRunner.class) @SpringBootTest public class WedulPlayTest { WedulPlayService wedulPlayService; @Autowired @Qualifier("wedulPlayRepository") WedulPlayRepository wedulPlayRepository; @Before public void setup() { wedulPlayService = new WedulPlayService(wedulPlayRepository); } @Test public void whenValidParameter_thenSuccessFind() { List<WedulPlay> list = wedulPlayService.findAll(); assertNotNull(list); } @Test public void whenValidParameter_thenSuccessSave() { Exception ex = null; try { wedulPlayService.save(WedulPlay.builder().title("안녕 이건 테스트야").user("위들").startAt(1242421424).endAt(23214124).build()); } catch (Exception exception) { ex = exception; } assertTrue(null == ex); } @Test public void whenValidParameter_thenSuccessFindByUser() { Exception ex = null; try { WedulPlay play = wedulPlayService.findByUser("위들"); assertThat(play, is(IsNull.notNullValue())); } catch (Exception exception) { ex = exception; } assertTrue(null == ex); } } | cs |
설정이 간단하다.
나중에 이용해 먹어야지
자세한 소스코드는 여기 참조
https://github.com/weduls/spring_elastic
'web > Spring' 카테고리의 다른 글
heroku 에서 spring boot jar파일 deploy시 Web process failed to bind to $PORT within 90 seconds of launch 에러 처리 (0) | 2019.03.31 |
---|---|
creating bean with name 'webMvcRequestHandlerProvider' defined in URL 에러처리 (0) | 2019.03.27 |
kafka docker에 간단 설치 후 Spring boot 연동 테스트 (0) | 2019.01.25 |
Spring Reactive Web Application (0) | 2019.01.12 |
생성한 Custom validation으로 에러메시지 출력하기 (4) | 2018.12.25 |