您的位置:首页 > 编程语言 > Java开发

SpringBoot集成elasticsearch支持字段映射

2020-02-15 00:01 1261 查看

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
  • 收藏
  • 分享
  • 文章举报
zhouyuhhu 发布了2 篇原创文章 · 获赞 1 · 访问量 160 私信 关注
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: