Intro::
์ฝํ๋ฆฐ ์คํ๋ง์ ํ์ฉํ ์๋ผ์คํฑ์์น ๋ํ๋จผํธ ์ธ๋ฑ์ฑ ํ๋ก์ ํธ ์ ๋ฆฌ์
๋๋ค. ์๋ผ์คํฑ์์น ์ค๋ฌด๊ฐ์ด๋์์ ์ ๊ณตํ๋ ์ค๋
์ท์ ์ฌ์ฉํ์์ต๋๋ค.
์ด๊ธฐ ์ค์
docker-compose.yml
services:
es01:
image: docker.elastic.co/elasticsearch/elasticsearch:7.8.1
container_name: es01
environment:
- cluster.name=cluster
- node.name=es01
- network.host=0.0.0.0
- http.port=9200
- transport.tcp.port=9300
- cluster.initial_master_nodes=es01
- path.repo=/es/book_backup/search_example
- bootstrap.memory_lock=true
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
ulimits:
memlock:
soft: -1
hard: -1
volumes:
- data01:/usr/share/elasticsearch/data
- ./search_example:/es/book_backup/search_example
ports:
- 9200:9200
- 9300:9300
networks:
- elastic
kibana:
image: docker.elastic.co/kibana/kibana:7.8.1
container_name: kibana
restart: always
environment:
ELASTICSEARCH_HOSTS: http://es01:9200
ports:
- 5601:5601
depends_on:
- es01
networks:
- elastic
volumes:
data01:
driver: local
networks:
elastic:
driver: bridge
Kotlin
๋ณต์ฌ
build.gradle.kts
plugins {
id("org.springframework.boot") version "3.3.0"
id("io.spring.dependency-management") version "1.1.5"
kotlin("jvm") version "1.9.24"
kotlin("plugin.spring") version "1.9.24"
}
group = "elastic"
version = "0.0.1-SNAPSHOT"
java {
toolchain {
languageVersion = JavaLanguageVersion.of(17)
}
}
repositories {
mavenCentral()
}
dependencies {
implementation("org.elasticsearch.client:elasticsearch-rest-high-level-client:7.8.1")
implementation("org.springframework.boot:spring-boot-starter-web")
implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
implementation("org.jetbrains.kotlin:kotlin-reflect")
implementation("org.springframework.boot:spring-boot-starter-validation")
developmentOnly("org.springframework.boot:spring-boot-devtools")
testImplementation("org.springframework.boot:spring-boot-starter-test")
testImplementation("org.jetbrains.kotlin:kotlin-test-junit5")
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
}
kotlin {
compilerOptions {
freeCompilerArgs.addAll("-Xjsr305=strict")
}
}
tasks.withType<Test> {
useJUnitPlatform()
}
Kotlin
๋ณต์ฌ
Elasticsearch
๋์ปค ์ปจํ
์ด๋๋ก ์คํํ Elasticsearch์ ๋ฒ์ ์ด 7.8.1์ธ ๊ฒฝ์ฐ, ๋ณด์ ์ค์ ์ด ๊ธฐ๋ณธ์ ์ผ๋ก ํ์ฑํ๋์ด ์์ง ์์ต๋๋ค. 8๋ฒ์ ์ด์๋ถํฐ๋ ๋ณด์ ์ค์ ์ด ๊ธฐ๋ณธ์ ์ผ๋ก ํ์ฑํ๋์ด ์์ผ๋ฏ๋ก ์ฃผ์๊ฐ ํ์ํฉ๋๋ค. ๋ํ Elasticsearch๋ ๋ฒ์ ์ ๋ํ ์ข
์์ฑ์ด ๊ฐํ๊ธฐ ๋๋ฌธ์ ๋ฒ์ ํธํ์ฑ์ ์ ์ํด์ผ ํฉ๋๋ค.
์๋ผ์คํฑ์์น๋ฅผ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ ํฌ๊ฒ ์ธ๊ฐ์ง๊ฐ ์กด์ฌํฉ๋๋ค.
1.
spring data elasticsearch
2.
elasitcsearch-rest-client
3.
rest-high-level-client
ํด๋น ํ๋ก์ ํธ์์๋ rest-high-level-client ๋ฅผ ์ฌ์ฉํ์์ต๋๋ค.
// ElasticsearchConfig ํ์ผ
package elastic.elasticSpring.core.config
import org.apache.http.HttpHost
import org.apache.http.impl.nio.client.HttpAsyncClientBuilder
import org.elasticsearch.client.RestClient
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
class ElasticsearchConfig {
@Value("\${elasticsearch.host}")
lateinit var host: String
@Value("\${elasticsearch.port}")
lateinit var esPort: String
@Bean
fun restHighLevelClient(): RestHighLevelClient {
return RestHighLevelClient(
RestClient.builder(
HttpHost(host, esPort.toInt(), "http")
).setHttpClientConfigCallback { httpClientBuilder: HttpAsyncClientBuilder ->
httpClientBuilder
}
)
}
}
Kotlin
๋ณต์ฌ
๊ตฌํ
๋จ์ผ ๋ํ๋จผํธ ์ธ๋ฑ์ฑ
fun add(movie: Movie): IndexResponse {
val indexRequest = IndexRequest(index)
.source(objectMapper.writeValueAsString(movie), XContentType.JSON)
if (!movie.id.isNullOrEmpty()) {
indexRequest.id(movie.id)
}
return restHighLevelClient.index(indexRequest, RequestOptions.DEFAULT)
}
Kotlin
๋ณต์ฌ
bulk API ๋ฅผ ํตํ ๋ํ๋จผํธ ์ธ๋ฑ์ฑ
fun bulkIndex(movieList: List<Movie>): BulkResponse {
val bulkRequest = BulkRequest()
for (movie in movieList) {
val indexRequest = IndexRequest(index)
.source(objectMapper.writeValueAsString(movie), XContentType.JSON)
if (!movie.id.isNullOrEmpty()) {
indexRequest.id(movie.id)
}
bulkRequest.add(indexRequest)
}
return restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT)
}
Kotlin
๋ณต์ฌ
_update_by_query๋ฅผ ํตํ ๋ํ๋จผํธ ์์
fun addGenre(movieDto: MovieAddGenreRequestDto): BulkByScrollResponse {
val updateByQueryRequest = UpdateByQueryRequest(index)
val script = Script(
ScriptType.INLINE,
"painless",
"ctx._source.genreAlt.add(params.genre)",
mapOf("genre" to movieDto.genre)
)
val query = QueryBuilders.matchQuery("movieNm", movieDto.movieNm)
updateByQueryRequest.setScript(script)
updateByQueryRequest.setQuery(query)
return restHighLevelClient.updateByQuery(updateByQueryRequest, RequestOptions.DEFAULT)
}
Kotlin
๋ณต์ฌ