목차
dependencies {
// Elasticsearch Java 클라이언트
implementation 'co.elastic.clients:elasticsearch-java:8.15.2'
implementation 'org.elasticsearch.client:elasticsearch-rest-client:8.15.2'
}
application.yml
설정
spirng:
elasticsearch:
uris: ${ELASTICCLOUD_ENDPOINT}
username: elastic
password: ${ELASTICCLOUD_PASSWORD}
elasticsearch:
uris: ${ELASTICCLOUD_ENDPOINT}
username: elastic
password: ${ELASTICCLOUD_PASSWORD}
/batch/infrastructure/config/ElasticsearchConfig.java
구현
@Configuration
@RequiredArgsConstructor
public class ElasticsearchConfig{
private static final Logger logger = LoggerFactory.getLogger(ElasticsearchConfig.class);
// application.yml에서 설정된 값들을 가져오기
@Value("${elasticsearch.uris}")
private String elasticsearchUri;
@Value("${elasticsearch.username}")
private String elasticsearchUsername;
@Value("${elasticsearch.password}")
private String elasticsearchPassword;
/**
* ElasticsearchClient 빈을 생성하여 Spring 컨텍스트에 등록
* @return ElasticsearchClient
*/
@Bean
public ElasticsearchClient elasticsearchClient() {
// 기본 자격 증명 공급자 설정 (사용자 이름, 비밀번호)
BasicCredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(elasticsearchUsername, elasticsearchPassword));
// Elasticsearch 연결을 위한 RestClientBuilder 설정
RestClientBuilder builder = RestClient.builder(HttpHost.create(elasticsearchUri))
.setHttpClientConfigCallback(httpClientBuilder -> httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider));
// RestClient 및 Transport 생성
RestClient restClient = builder.build();
ElasticsearchTransport transport = new RestClientTransport(restClient, new JacksonJsonpMapper());
// ElasticsearchClient 생성
return new ElasticsearchClient(transport);
}
}
/batch/infrastructure/config/ElasticsearchInitializer.java
공시자료 인덱스 생성
@Service
@RequiredArgsConstructor
public class ElasticsearchInitializer {
private final ElasticsearchClient elasticsearchClient;
@PostConstruct
public void configureElasticsearchIndex() throws IOException {
boolean indexExists = elasticsearchClient.indices().exists(e -> e.index("disclosures")).value();
if (!indexExists) {
createDisclosureIndex(elasticsearchClient);
}
}
private void createDisclosureIndex(ElasticsearchClient client) throws IOException {
String indexSettings = """
{
"settings": {
"analysis": {
"analyzer": {
"nori_analyzer": {
"type": "custom",
"tokenizer": "nori_tokenizer",
"filter": ["lowercase"]
}
}
}
},
"mappings": {
"properties": {
"corpName": {
"type": "text",
"analyzer": "nori_analyzer"
},
"reportNm": {
"type": "text",
"analyzer": "nori_analyzer"
},
"rceptDt": {
"type": "date",
"format": "yyyyMMdd"
}
}
}
}
""";
client.indices().create(c -> c
.index("disclosures")
.withJson(new StringReader(indexSettings))
);
LoggerFactory.getLogger(ElasticsearchInitializer.class).info("Successfully created 'disclosures' index with Nori analyzer.");
}
}
package com.tradingtrends.batch.domain.model.Entity;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.*;
import java.time.LocalDateTime;
@Getter
@Setter
@NoArgsConstructor
@ToString
@Document(indexName = "disclosures")
@Setting(settingPath = "elastic/document-setting.json")
@Mapping(mappingPath = "elastic/document-mapping.json")
public class DisclosureDocument {
@Id
private String rceptNo;
@Field(type = FieldType.Text)
private String corpName;
@Field(type = FieldType.Text)
private String corpCode;
@Field(type = FieldType.Text)
private String reportNm;
@Field(type = FieldType.Text)
private String rceptDt;
@Field(type = FieldType.Date, format = DateFormat.date_time)
private LocalDateTime loadDt;
@Field(type = FieldType.Text)
private String rawXmlData; // XML 원본 데이터를 저장
}
Elasticsearch 관련 Service 파일에 다음과 같은 메서드를 작성하여 데이터 인덱싱 요청