效果如下:以下是个人理解,如果有更好的方案,希望留言,共同探讨
解决方案及部分源码分析整理
spring-data-elasticsearch 创建 es中的 index
elasticsearchTemplate.createIndex()
elasticsearchTemplate.putMapping()
第一个是创建索引
第二个是创建索引中type对应的mapping 映射
下面是putMapping中的多态中的一种, 查找有无Es自带的Mapping注解,如果有,找到注解对应的mapper.xml配置文件
如果有则直接使用xml配置,如果没有利用XContentBuilder 构建 mapping
xContentBuilder = MappingBuilder.buildMapping(clazz, persistentEntity.getIndexType(), property.getFieldName(), persistentEntity.getParentType());
上面的这段代码才是解析mapping的关键 因为是私有属性,无法调用,所以不能再putMapping前构造 mapping,我的解决方案是先利用原有解析创建mapping,然后从es服务器上获得构建好的 type mapping 重构
看下@Field注解将对应成员变量上的注解遍历,拼凑XctentBuilder
在构建时支持三种方案,第一种是 JSONObject.toJSONString()转换得到的json
第二种是map
第三种是 基于XContentBuilder
默认使用第三种。
默认加载mapping方式是不提供部分参数的。只有利用自定义注解的形式去创建,或者直接使用 xml方式获取
实施步骤:
第一步:maven 引入依赖
第二部:配置yml文件
第三部:编写实体,框起来的为自定义注解
自定义注解
第四部:项目启动重构index中的mapping
/**
* @author yzxRevange
* date 2019-09-04
* 对自定义注解实体信息转换映射成 mapping
*/
public class EntityMapping {
/**
* 重构 index mapping 加入自定义注解
*
* @param entity 对应实体
* @param epe 转换后得到的关于 type _mapping 部分信息
* @param serverMapping 服务端 mapping
* @return
*/
public String buildMappingByOnwerAnnotations(Class<?> entity, ElasticsearchPersistentEntity epe, Map serverMapping) {
final Map<String, Object> map = Maps.newHashMap();
map.putAll(serverMapping);
//获得type
String indexType = epe.getIndexType();
//通过获得模板是否动态模板
DynamicMappings dynamicMappings = entity.getAnnotation(DynamicMappings.class);
if (dynamicMappings.dynamic()) {
map.put("dynamic", dynamicMappings.dynamic());
}
//添加自定义注解配置
Map<String, Object> prop = (Map<String, Object>) map.get("properties");
prop.forEach((key, value) -> {
try {
Field field = entity.getDeclaredField(key);
//对关键字中的属性写入map中
KeyWord keyWord = field.getDeclaredAnnotation(KeyWord.class);
Map<String, Object> fieldsMap = getKeyIfExistsAndCreator((Map<String, Object>) value, "fields");
Map<String, Object> keywordMap = getKeyIfExistsAndCreator(fieldsMap, "keyword");
keywordMap.put("type", keyWord.type());
keywordMap.put("ignore_above", keyWord.ignore_above());
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
});
Map<String, Object> mapping = Maps.newHashMap();
mapping.put(indexType, map);
return JSONObject.toJSONString(mapping);
}
/**
* 构造mapping
* @param map
* @param key
* @return
*/
private Map<String, Object> getKeyIfExistsAndCreator(Map<String, Object> map, String key) {
if (map.get(key) == null) {
Map<String, Object> returnType = Maps.newHashMap();
map.put(key, returnType);
}
return (Map<String, Object>) map.get(key);
}
}