Spring Data JPA에서 DB의 테이블에 맞게Entity를 작성하는 것처럼, Spring Data Elasticsearch에서 인덱스에 맞게Document를 작성해야 한다.
... dependencies { implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springframework.boot:spring-boot-starter-data-elasticsearch' developmentOnly 'org.springframework.boot:spring-boot-devtools' runtimeOnly 'com.mysql:mysql-connector-j' testImplementation 'org.springframework.boot:spring-boot-starter-test' testRuntimeOnly 'org.junit.platform:junit-platform-launcher' } ...

spring: datasource: url: jdbc:mysql://localhost:3306/coupang username: root password: password123 driver-class-name: com.mysql.cj.jdbc.Driver jpa: hibernate: ddl-auto: update show-sql: true elasticsearch: uris: http://localhost:9200 logging: level: org.elasticsearch.client: TRACE
@Document(indexName = "products") // products 인덱스 생성 @Setting(settingPath = "/elasticsearch/product-settings.json") public class ProductDocument { @Id private String id; @MultiField(mainField = @Field(type = FieldType.Text, analyzer = "products_name_analyzer"), otherFields = { @InnerField(suffix = "auto_complete", type = FieldType.Search_As_You_Type, analyzer = "nori") } ) private String name; @Field(type = FieldType.Text, analyzer = "products_description_analyzer") private String description; @Field(type = FieldType.Integer) private Integer price; @Field(type = FieldType.Double) private Double rating; @MultiField(mainField = @Field(type = FieldType.Text, analyzer = "products_category_analyzer"), otherFields = { @InnerField(suffix = "raw", type = FieldType.Keyword) } ) private String category; public ProductDocument(Long id, String name, String description, Integer price, Double rating, String category) { this.id = id; this.name = name; this.description = description; this.price = price; this.rating = rating; this.category = category; } // getter, setter 메서드 public String getName() { return name; } public void setName(String name) { this.name = name; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } public Integer getPrice() { return price; } public void setPrice(Integer price) { this.price = price; } public Double getRating() { return rating; } public void setRating(Double rating) { this.rating = rating; } public String getCategory() { return category; } public void setCategory(String category) { this.category = category; } }
“settings” 필드 안의 값만 작성해야 한다. “mappings”에 대한 정보조차 적지 않는다.
(”mappings" 정보는 Document 객체에 기입하기 때문에 적을 필요가 없다.){ "analysis": { "filter": { "product_synonyms": { "type": "synonym", "synonyms": [ "samsung, 삼성", "apple, 애플", "노트북, 랩탑, 컴퓨터, computer, laptop, notebook", "전화기, 휴대폰, 핸드폰, 스마트폰, 휴대전화, phone, smartphone, mobile phone, cell phone", "아이폰, iphone", "맥북, 맥, macbook, mac" ] } }, "analyzer": { "products_name_analyzer": { "char_filter": [], "tokenizer": "nori_tokenizer", "filter": [ "nori_part_of_speech", "nori_readingform", "lowercase", "product_synonyms" ] }, "products_description_analyzer": { "char_filter": ["html_strip"], "tokenizer": "nori_tokenizer", "filter": [ "nori_part_of_speech", "nori_readingform", "lowercase" ] }, "products_category_analyzer": { "char_filter": [], "tokenizer": "nori_tokenizer", "filter": [ "nori_part_of_speech", "nori_readingform", "lowercase" ] } } } }
public interface ProductDocumentRepository extends ElasticsearchRepository<ProductDocument, String> { }
DELETE /products // 인덱스 삭제 GET /products // 잘 삭제됐는 지 확인

GET /products