SpringBoot集成elasticsearch支持字段映射
SpringBoot集成elasticsearch支持自动@Field别名存储问题
1、问题描述
Java代码属性字段多使用驼峰命名法,而mysql、elasticsearch等数据存储系统中字段多采用下划线命名法。mysql使用tk.mybatis+@Column注解即可轻松实现Java对象持久化存储字段映射,本文主要解决在elasticsearch集成过程中遇到的问题及如果字段映射
2、集成版本列表
SpringCloud、SpringBoot、elasticsearch版本依赖度很高,这也是这次集成遇到的大问题,且elasticsearch在3.2以后版本才引入了@Field的name属性,因此将此次的集成版本列出如下:
项目 | 版本 |
---|---|
SpringCloud | Greenwich.SR2 |
SpringBoot | 2.1.2 |
elasticsearch | 3.2.3 |
3、启动yml文件配置
spring: data: elasticsearch: repositories: enabled: true cluster-name: "es-bigdata" cluster-nodes: xx.xx.xx.xx:9300,xx.xx.xx.xx:9300,xx.xx.xx.xx:9300
4、SpringBoot启动类上需要加注解
@EnableElasticsearchRepositories(basePackages = "com.xx.xx.xx.repository")
5、Java持久化对象定义
package com.xx.xx.xx.model.es; import lombok.Data; import org.springframework.data.annotation.Id; import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.annotations.Field; import org.springframework.data.elasticsearch.annotations.FieldType; import org.springframework.data.elasticsearch.annotations.Setting; import org.springframework.format.annotation.NumberFormat; @Data @Document(indexName = "forecast_match_day", type = "table") @Setting(settingPath = "setting/elasticsearchSetting.json") public class ForecastMatchDayPO { /** * 主键,通过表内唯一索引字段组合拼接,作为ES表结构id,实现upsert能力 */ @Id @Field(name = "id", type = FieldType.Keyword) private String id; /** * 预测日期(格式yyyy-MM-dd) */ @Field(name = "forecast_date", type = FieldType.Keyword) private String forecastDate; /** * 高度编码 */ @Field(name = "high", type = FieldType.Keyword) private String high; /** * 高度名称 */ @Field(name = "high_name", type = FieldType.Text) private String highName; /** * 需求数量 */ @Field(name = "demand_num", type = FieldType.Integer) private Integer demandNum; /** * 创建时间(格式yyyy-MM-dd HH:mm:ss) */ @Field(name = "create_time", type = FieldType.Text) private String createTime; /** * 更新时间(格式yyyy-MM-dd HH:mm:ss) */ @Field(name = "update_time", type = FieldType.Text) private String updateTime; }
6、Repository定义
package com.xx.xx.xx.repository.es; import com.xx.xx.dal.model.es.ForecastMatchDayPO; import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; public interface ForecastMatchDayRepository extends ElasticsearchRepository<ForecastMatchDayPO, String> { }
7、最后一个坑
前面的集成动作都做好了之后,项目启动正常,es上也自动成功建好了索引库,字段也都是下划线命名风格;但是,但是…当通过save接口往es里灌数据之后,发现存储的数据又是使用Java的驼峰命名风格字段存储了,此时elasticsearch中字段无故出现两套,以下划线命名风格一套,以驼峰命名风格一套,而且存储都是驼峰命名的字段有值,下划线的字段无值。
8、解决方案
苦苦搜索各大技术博客网站而不得,只得debug跟踪底层代码,发现ElasticsearchTemplate初始化时,持久化了一个ResultsMapper对象,该对象中的EntityMapper负责对象数据的json化等工作,而EntityMapper实现有两,DefaultEntityMapper和ElasticsearchEntityMapper(从3.2版本后引入),而平台初始化默认用的是DefaultEntityMapper实现。上面我们也提到,elasticsearch版本从3.2以后版本才加入了@Field的name属性,引入自带的字段别名映射能力,而ElasticsearchEntityMapper正是用于解决该问题,因此,需要自定义注入ElasticsearchTemplate的bean对象,代码如下:
package com.xx.xx.xx.config; import org.elasticsearch.client.Client; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.elasticsearch.core.ElasticsearchEntityMapper; import org.springframework.data.elasticsearch.core.ElasticsearchTemplate; import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter; @Configuration public class ElasticsearchConfig { @Bean public ElasticsearchTemplate elasticsearchTemplate(Client client, ElasticsearchConverter converter) { try { return new ElasticsearchTemplate(client, new ElasticsearchEntityMapper(converter.getMappingContext(), null)); } catch (Exception ex) { throw new IllegalStateException(ex); } } }
至此,字段映射问题最终解决,集成工作初告一段落。
- 点赞 1
- 收藏
- 分享
- 文章举报
- Javaweb中文乱码问题
- 免XML的SpringMVC配置
- spring security 5.0 密码未加密报错
- SpringCloud学习路线
- 使用Java Reflection技术实现ActionForm数据装载
- java8 stream
- struts2的s:iterator 标签 详解
- 根据先序序列和中序序列生成二叉树(Java)
- Java自动拆装箱
- Java堆内存详解
- Jdk环境配置教程
- 解决Maven无法下载fastdfs-client-java依赖
- 关于部署springboot项目时,出现“Error creating bean with name 'bindingService' defined in class path”的错误记录
- 记录fastdfs-client-java的依赖无法从maven下载的问题,解决办法
- SpringBoot Quartz指定时间执行任务及取消该定时任务
- JAVA技术之——反射 学习笔记-2 Field
- JAVA技术之——反射 学习笔记-3 Method
- Java中JDK,JRE和JVM之间的关系-(转载)
- springBoot整合Junt Failed to load ApplicationContext问题解决*
- Myeclipse出现 the user operation is waiting和launching client问题