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
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() }
Elasticsearch
๋์ปค ์ปจํ
์ด๋๋ก ์คํํ Elasticsearch์ ๋ฒ์ ์ด 7.8.1์ธ ๊ฒฝ์ฐ, ๋ณด์ ์ค์ ์ด ๊ธฐ๋ณธ์ ์ผ๋ก ํ์ฑํ๋์ด ์์ง ์์ต๋๋ค. 8๋ฒ์ ์ด์๋ถํฐ๋ ๋ณด์ ์ค์ ์ด ๊ธฐ๋ณธ์ ์ผ๋ก ํ์ฑํ๋์ด ์์ผ๋ฏ๋ก ์ฃผ์๊ฐ ํ์ํฉ๋๋ค. ๋ํ Elasticsearch๋ ๋ฒ์ ์ ๋ํ ์ข
์์ฑ์ด ๊ฐํ๊ธฐ ๋๋ฌธ์ ๋ฒ์ ํธํ์ฑ์ ์ ์ํด์ผ ํฉ๋๋ค.
์๋ผ์คํฑ์์น๋ฅผ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ ํฌ๊ฒ ์ธ๊ฐ์ง๊ฐ ์กด์ฌํฉ๋๋ค.
- spring data elasticsearch
- elasitcsearch-rest-client
- 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 } ) } }
ย
๊ตฌํ
๋จ์ผ ๋ํ๋จผํธ ์ธ๋ฑ์ฑ
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) }
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) }
_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) }
References::
ย
Loading Comments...