업무 도중 RDB와 ES(ElasticSearch) 데이터 싱크 기능이 오류가 발생했다. 기존에 발생하지 않았던 오류인데 기존 테이블 정보에서 추가를 한 후 발생하였다.
fireInsuranceRegDt 컬럼은 타입이 String이다. 실제 들어가 있는 데이터는 2022-01-01 처럼 Date형식으로 보이지만 실제로는 Date가 아닌 String 타입으로 저장되어 있다.
그리고 구글링을 통해 찾아보니 Dynamic Mapping이라는 키워드가 나왔다.
문서를 봐도 명확하게 DynamicMapping이 어떤 기준으로 Date형태로 저장했는지는 아직 찾지 못했지만, 추측하기로는 실제 데이터가 Date처럼 되어있기 때문이 아니었나라고 생각한다..
너무 똑똑해도 이런 문제가 발생할 수 있구나 라는 걸 느꼈다.
Bulk operation has failures. Use ElasticsearchException.getFailedDocuments() for detailed messages [{6075=ElasticsearchException[Elasticsearch exception [type=mapper_parsing_exception, reason=failed to parse field [fireInsuranceRegDt] of type [date] in document with id '6075'. Preview of field's value: '']]; nested: ElasticsearchException[Elasticsearch exception [type=illegal_argument_exception, reason=cannot parse empty date]];, 6078=ElasticsearchException[Elasticsearch exception [type=mapper_parsing_exception, reason=failed to parse field [fireInsuranceRegDt] of type [date] in document with id '6078'. Preview of field's value: '']]; nested: ElasticsearchException[Elasticsearch exception [type=illegal_argument_exception, reason=cannot parse empty date]];, 47=ElasticsearchException[Elasticsearch exception [type=mapper_parsing_exception, reason=failed to parse field [fireInsuranceRegDt] of type [date] in document with id '47'. Preview of field's value: '']]; nested: ElasticsearchException[Elasticsearch exception [type=illegal_argument_exception, reason=cannot parse empty date]];, 983=ElasticsearchException[Elasticsearch exception [type=mapper_parsing_exception, reason=failed to parse field [fireInsuranceRegDt] of type [date] in document with id '983'. Preview of field's value: '']]; nested: ElasticsearchException[Elasticsearch exception [type=illegal_argument_exception, reason=cannot parse empty date]];,...
- 테이블 싱크 작업을 통해 fireInsuranceRegDt 컬럼이 Date 형식으로 저장되었다.(실제로는 String)
- 그 후에 테이블 정보를 수정한 후 다시 싱크 작업을 하니 Date 형식에는 ''가 들어갈 수 없는 오류가 발생했다.
- 구글링을 통해 Dynamic Mapping 키워드를 찾았다.
해결을 위해 구글링을 통해 찾은 게 해당 ES field(RDB의 Column 개념)에 어노테이션을 적용해 DynamicMapping을 적용시키지 않게 처리할 수 있는 것을 발견하였다.
DynamicMapp@DynamicMapping(DynamicMappingValue.false)
하지만 아쉽게도 위 방법을 통해 테스트를 하기 전 사수님께서 해결하셔서 테스트를 하기 전 해결되었다 😅.
FieldType.Keyword으로 지정된 값을 FieldType.Text으로 변경하고 ES의 Index(RDB의 Table 개념)를 삭제한 후 다시 싱크를 맞추는 식으로 문제를 해결하였다.
마지막으로 DynamicMapping의 특징에 대해 간략하게 정리하면
ES는 기본적으로 schemaless이기 때문에, 매핑 정보가 없어도 알아서 적절한 매핑을 생성해줌
자동으로 생성된 매핑 이후, 다른 타입의 데이터가 들어온다면 색인되지 않음
dynamic mapping 기능을 명시적으로 해제해 주어야 함