상황
앞선 포스팅에서는 엘라스틱 서치를 설치하는 작업을 해보았다.
2025.11.13 - [Back/Kotlin] - Elasticsearch 활용한 검색 구현하기 - 1 (Docker로 Elasticsearch + Kibana 구축)
이제는 Springboot + Kotlin을 활용하여 구현을 진행할 차례이다.
[개발환경]
- Kotlin: 1.9.25
- Java: 17
- Spring Boot: 3.5.7
적용
✔️1. 세팅 및 설정파일 작성
1. build.gradle.kts에 의존성 추가
implementation("org.springframework.boot:spring-boot-starter-data-elasticsearch")
Spring Data Elasticsearch는 Spring과 Elasticsearch를 쉽게 연동할 수 있도록 도와준다.
의존성 추가를 해주었으면, build 진행해준다.
2. 설정파일 작성
설치가 완료되고 나면 config를 작성한다.
✅2-1. resources 하위에 application.yml 작성한다.
📌논외지만, 참고!
- src/main/kotlin/ : 실행 가능한 코드
- src/main/resources/ : 코드가 사용하는 데이터 (설정, 이미지, HTML 등)
spring:
elasticsearch:
uris: http://localhost:9200
data:
elasticsearch:
repositories:
enabled: true
✅2.2 Elasticsearch 연결을 위한 Config Class 만들기
Spring Boot 3.x + Spring Data Elasticsearch 5.x 이상에서는 자동 설정이 강력해서 이 Config 클래스가 선택사항이다.
하지만, 추후에 SSL 설정, 타임아웃 설정등의 커스터마이징이 필요할 수 있으니 만들어두려고 한다.
(간단한 기본 설정만으로도 구현하고 싶다면, yml 파일만으로도 충분하다.)
import org.springframework.beans.factory.annotation.Value
import org.springframework.context.annotation.Configuration
import org.springframework.data.elasticsearch.client.ClientConfiguration
import org.springframework.data.elasticsearch.client.elc.ElasticsearchConfiguration
import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories
@Configuration
@EnableElasticsearchRepositories
class ElasticsearchConfig(
@Value("\${spring.elasticsearch.uris}") private val host: String,
) : ElasticsearchConfiguration() {
override fun clientConfiguration(): ClientConfiguration {
return ClientConfiguration.builder()
.connectedTo(host.removePrefix("http://")) // "localhost:9200"
// .withConnectTimeout(Duration.ofSeconds(5))
// .withSocketTimeout(Duration.ofSeconds(30))
.build()
}
}
✔️2. 실행 코드 작성
Entity
@Document(indexName = "products")
data class Product(
@Id
val id: String? = null,
@Field(type = FieldType.Text)
val name: String,
@Field(type = FieldType.Text)
val description: String,
@Field(type = FieldType.Keyword)
val category: String,
@Field(type = FieldType.Double)
val price: Double
)
Controller
@RestController
@RequestMapping("/api/products")
class ProductController(
private val searchService: ProductSearchService
) {
@PostMapping
fun addProduct(@RequestBody product: Product): Product {
return searchService.saveProduct(product)
}
@GetMapping("/search")
fun search(@RequestParam keyword: String): List<Product> {
return searchService.searchByKeyword(keyword)
}
@GetMapping
fun getAll(): List<Product> {
return searchService.getAllProducts()
}
}
Service
@Service
class ProductSearchService(
private val productRepository: ProductRepository,
private val elasticsearchOperations: ElasticsearchOperations
) {
fun saveProduct(product: Product): Product {
return productRepository.save(product)
}
fun searchByKeyword(keyword: String): List<Product> {
return productRepository.findByNameContaining(keyword)
}
fun searchWithCriteria(keyword: String): SearchHits<Product> {
val criteria = Criteria.where("name").contains(keyword)
.or("description").contains(keyword)
val query = CriteriaQuery(criteria)
return elasticsearchOperations.search(query, Product::class.java)
}
fun getAllProducts(): List<Product> {
return productRepository.findAll().toList()
}
}
Repository
@Repository
interface ProductRepository : ElasticsearchRepository<Product, String> {
fun findByName(name: String): List<Product>
fun findByNameContaining(keyword: String): List<Product>
fun findByCategoryAndPriceLessThan(category: String, price: Double): List<Product>
}
✔️3. 실제 실행해보기
API 호출하여 작성한 코드가 정상 동작하는지 확인해보자.
나는 postman 을 이용해 테스트를 진행했다.
# 데이터 추가
curl -X POST http://localhost:8080/api/products \
-H "Content-Type: application/json" \
-d '{
"name": "MacBook Pro",
"description": "강력한 성능의 노트북",
"category": "electronics",
"price": 2500000
}'
# 검색
curl "http://localhost:8080/api/products/search?keyword=MacBook"

✔️4. Kibana 접속해 데이터 확인해보기
http://localhost:5601 로 웹에서 접속하고, Analytics -> Discover -> Create Data View 순으로 이동한다.

Create data view 버튼을 누르면 products 인덱스가 생성되어있다!
그 후 name, index pattern(생성된 인덱스를 입력) Timestamp field를 설정한 후 view를 생성하면 생성된 데이터를 확인할 수 있다.
댓글