diff --git a/easy-es-annotation/pom.xml b/easy-es-annotation/pom.xml
index a4acc306..a2ab8645 100644
--- a/easy-es-annotation/pom.xml
+++ b/easy-es-annotation/pom.xml
@@ -18,10 +18,4 @@
8
-
-
- org.projectlombok
- lombok
-
-
\ No newline at end of file
diff --git a/easy-es-annotation/src/main/java/org/dromara/easyes/annotation/IndexField.java b/easy-es-annotation/src/main/java/org/dromara/easyes/annotation/IndexField.java
index 32bb48cf..de539e9d 100644
--- a/easy-es-annotation/src/main/java/org/dromara/easyes/annotation/IndexField.java
+++ b/easy-es-annotation/src/main/java/org/dromara/easyes/annotation/IndexField.java
@@ -1,7 +1,6 @@
package org.dromara.easyes.annotation;
-
import org.dromara.easyes.annotation.rely.*;
import java.lang.annotation.ElementType;
@@ -80,6 +79,13 @@ public @interface IndexField {
*/
boolean ignoreCase() default false;
+ /**
+ * 长度超过ignore_above设置的字符串将不会被索引或存储 keyword_text默认值为256
+ *
+ * @return 索引字段最大长度
+ */
+ int ignoreAbove() default -1;
+
/**
* 默认嵌套类
*
diff --git a/easy-es-annotation/src/main/java/org/dromara/easyes/annotation/IndexName.java b/easy-es-annotation/src/main/java/org/dromara/easyes/annotation/IndexName.java
index 6de3a71a..5414b7f9 100644
--- a/easy-es-annotation/src/main/java/org/dromara/easyes/annotation/IndexName.java
+++ b/easy-es-annotation/src/main/java/org/dromara/easyes/annotation/IndexName.java
@@ -1,7 +1,6 @@
package org.dromara.easyes.annotation;
import org.dromara.easyes.annotation.rely.DefaultChildClass;
-import org.dromara.easyes.annotation.rely.RefreshPolicy;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
@@ -82,6 +81,4 @@ public @interface IndexName {
* @return CRUD作用的路由
*/
String routing() default "";
-
- RefreshPolicy refreshPolicy() default RefreshPolicy.GLOBAL;
}
diff --git a/easy-es-annotation/src/main/java/org/dromara/easyes/annotation/InnerIndexField.java b/easy-es-annotation/src/main/java/org/dromara/easyes/annotation/InnerIndexField.java
new file mode 100644
index 00000000..1f6b7572
--- /dev/null
+++ b/easy-es-annotation/src/main/java/org/dromara/easyes/annotation/InnerIndexField.java
@@ -0,0 +1,48 @@
+package org.dromara.easyes.annotation;
+
+
+import org.dromara.easyes.annotation.rely.Analyzer;
+import org.dromara.easyes.annotation.rely.FieldType;
+
+/**
+ * 内部字段索引注解
+ *
+ *
+ * @author yinlei
+ **/
+public @interface InnerIndexField {
+ /**
+ * 内部字段的前缀,必须指定,否则无存在意义,且不可重名,重名则以首次出现的为准
+ *
+ * @return 内部字段的前缀
+ */
+ String suffix();
+
+ /**
+ * 内部字段在es索引中的类型,必须指定,否则无存在意义
+ *
+ * @return 类型
+ */
+ FieldType fieldType();
+
+ /**
+ * 内部字段索引文档时用的分词器
+ *
+ * @return 分词器
+ */
+ String analyzer() default Analyzer.NONE;
+
+ /**
+ * 内部字段查询分词器
+ *
+ * @return 分词器
+ */
+ String searchAnalyzer() default Analyzer.NONE;
+
+ /**
+ * 内部字段长度超过ignore_above设置的字符串将不会被索引或存储 keyword_text默认值为256
+ *
+ * @return 索引内部字段最大长度
+ */
+ int ignoreAbove() default -1;
+}
diff --git a/easy-es-annotation/src/main/java/org/dromara/easyes/annotation/MultiIndexField.java b/easy-es-annotation/src/main/java/org/dromara/easyes/annotation/MultiIndexField.java
new file mode 100644
index 00000000..0a6a2c00
--- /dev/null
+++ b/easy-es-annotation/src/main/java/org/dromara/easyes/annotation/MultiIndexField.java
@@ -0,0 +1,30 @@
+package org.dromara.easyes.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 多字段索引注解
+ *
+ *
+ * @author yinlei
+ **/
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.FIELD)
+public @interface MultiIndexField {
+ /**
+ * 主字段信息
+ *
+ * @return 主字段信息
+ */
+ IndexField mainIndexField();
+
+ /**
+ * 内部字段信息
+ *
+ * @return 内部字段信息
+ */
+ InnerIndexField[] otherIndexFields() default {};
+}
diff --git a/easy-es-annotation/src/main/java/org/dromara/easyes/annotation/rely/FieldType.java b/easy-es-annotation/src/main/java/org/dromara/easyes/annotation/rely/FieldType.java
index 25c15b73..032cd4a0 100644
--- a/easy-es-annotation/src/main/java/org/dromara/easyes/annotation/rely/FieldType.java
+++ b/easy-es-annotation/src/main/java/org/dromara/easyes/annotation/rely/FieldType.java
@@ -29,6 +29,9 @@ public enum FieldType {
BINARY("binary"),
KEYWORD("keyword"),
TEXT("text"),
+ /**
+ * This type can not be used for @InnerIndexField
+ */
KEYWORD_TEXT("keyword&text"),
WILDCARD("wildcard"),
/**
diff --git a/easy-es-annotation/src/main/java/org/dromara/easyes/annotation/rely/RefreshPolicy.java b/easy-es-common/src/main/java/org/dromara/easyes/common/enums/RefreshPolicy.java
similarity index 65%
rename from easy-es-annotation/src/main/java/org/dromara/easyes/annotation/rely/RefreshPolicy.java
rename to easy-es-common/src/main/java/org/dromara/easyes/common/enums/RefreshPolicy.java
index f0dd2292..6ed5680f 100644
--- a/easy-es-annotation/src/main/java/org/dromara/easyes/annotation/rely/RefreshPolicy.java
+++ b/easy-es-common/src/main/java/org/dromara/easyes/common/enums/RefreshPolicy.java
@@ -1,4 +1,4 @@
-package org.dromara.easyes.annotation.rely;
+package org.dromara.easyes.common.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
@@ -7,17 +7,11 @@ import lombok.Getter;
* 数据刷新策略枚举
*
* Copyright © 2021 xpc1024 All Rights Reserved
- *
- * @see org.elasticsearch.action.support.WriteRequest.RefreshPolicy
**/
@AllArgsConstructor
public enum RefreshPolicy {
/**
- * 使用全局设置: easy-es.global-config.db-config.refresh-policy
- */
- GLOBAL(""),
- /**
- * 不立即刷新 (es默认的数据刷新策略)
+ * 默认不刷新
*/
NONE("false"),
/**
diff --git a/easy-es-common/src/main/java/org/dromara/easyes/common/utils/Assert.java b/easy-es-common/src/main/java/org/dromara/easyes/common/utils/Assert.java
index 89389d30..55d24594 100644
--- a/easy-es-common/src/main/java/org/dromara/easyes/common/utils/Assert.java
+++ b/easy-es-common/src/main/java/org/dromara/easyes/common/utils/Assert.java
@@ -61,7 +61,26 @@ public class Assert {
}
}
+ public static void notBlank(String str, String message) {
+ if (str == null || str.isEmpty() || !containsText(str)) {
+ throw new IllegalArgumentException(message);
+ }
+ }
+
+
+ private static boolean containsText(CharSequence str) {
+ int strLen = str.length();
+
+ for (int i = 0; i < strLen; ++i) {
+ if (!Character.isWhitespace(str.charAt(i))) {
+ return true;
+ }
+ }
+ return false;
+ }
+
private static boolean isEmpty(Object[] array) {
return array == null || array.length == 0;
}
+
}
diff --git a/easy-es-core/src/main/java/org/dromara/easyes/core/biz/EntityFieldInfo.java b/easy-es-core/src/main/java/org/dromara/easyes/core/biz/EntityFieldInfo.java
index 1ef19f41..1e9506da 100644
--- a/easy-es-core/src/main/java/org/dromara/easyes/core/biz/EntityFieldInfo.java
+++ b/easy-es-core/src/main/java/org/dromara/easyes/core/biz/EntityFieldInfo.java
@@ -1,16 +1,17 @@
package org.dromara.easyes.core.biz;
-import org.dromara.easyes.annotation.IndexField;
-import org.dromara.easyes.annotation.rely.FieldStrategy;
-import org.dromara.easyes.annotation.rely.FieldType;
-import org.dromara.easyes.core.config.GlobalConfig;
import com.alibaba.fastjson.serializer.NameFilter;
import lombok.AccessLevel;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
+import org.dromara.easyes.annotation.IndexField;
+import org.dromara.easyes.annotation.rely.FieldStrategy;
+import org.dromara.easyes.annotation.rely.FieldType;
+import org.dromara.easyes.core.config.GlobalConfig;
import java.lang.reflect.Field;
+import java.util.List;
/**
* es实体字段信息
@@ -47,6 +48,10 @@ public class EntityFieldInfo {
* 字段是否忽略大小写,默认不忽略 为true时则忽略大小写
*/
private boolean ignoreCase;
+ /**
+ * 字段最大索引长度
+ */
+ private Integer ignoreAbove;
/**
* 分词器
*/
@@ -86,6 +91,11 @@ public class EntityFieldInfo {
private String sqlSelect;
private NameFilter nameFilter;
+ /**
+ * 内部字段列表
+ */
+ private List innerFieldInfoList;
+
/**
* 存在 TableField 注解时, 使用的构造函数
*
@@ -95,7 +105,6 @@ public class EntityFieldInfo {
*/
public EntityFieldInfo(GlobalConfig.DbConfig dbConfig, Field field, IndexField tableField) {
this.column = field.getName();
-
// 优先使用单个字段注解,否则使用全局配置
if (tableField.strategy() == FieldStrategy.DEFAULT) {
this.fieldStrategy = dbConfig.getFieldStrategy();
@@ -115,4 +124,31 @@ public class EntityFieldInfo {
this.column = field.getName();
}
+ /**
+ * 内部字段
+ */
+ @Data
+ public static class InnerFieldInfo {
+ /**
+ * 内部字段名
+ */
+ private String column;
+ /**
+ * 内部字段类型
+ */
+ private FieldType fieldType;
+ /**
+ * 内部字段分词器
+ */
+ private String analyzer;
+ /**
+ * 内部字段查询分词器
+ */
+ private String searchAnalyzer;
+ /**
+ * 字段最大索引长度
+ */
+ private Integer ignoreAbove;
+ }
+
}
diff --git a/easy-es-core/src/main/java/org/dromara/easyes/core/biz/EntityInfo.java b/easy-es-core/src/main/java/org/dromara/easyes/core/biz/EntityInfo.java
index a0915ee5..129c52a1 100644
--- a/easy-es-core/src/main/java/org/dromara/easyes/core/biz/EntityInfo.java
+++ b/easy-es-core/src/main/java/org/dromara/easyes/core/biz/EntityInfo.java
@@ -8,7 +8,6 @@ import com.alibaba.fastjson.parser.deserializer.ExtraProcessor;
import com.alibaba.fastjson.serializer.SerializeFilter;
import lombok.Data;
import lombok.experimental.Accessors;
-import org.dromara.easyes.annotation.rely.RefreshPolicy;
import java.lang.reflect.Field;
import java.util.*;
@@ -178,8 +177,6 @@ public class EntityInfo {
*/
private final Map, List> classSimplePropertyPreFilterMap = new HashMap<>();
- private RefreshPolicy refreshPolicy;
-
/**
* 获取需要进行查询的字段列表
*
diff --git a/easy-es-core/src/main/java/org/dromara/easyes/core/biz/EsIndexParam.java b/easy-es-core/src/main/java/org/dromara/easyes/core/biz/EsIndexParam.java
index bbd0ba74..ca1d6ebe 100644
--- a/easy-es-core/src/main/java/org/dromara/easyes/core/biz/EsIndexParam.java
+++ b/easy-es-core/src/main/java/org/dromara/easyes/core/biz/EsIndexParam.java
@@ -2,6 +2,8 @@ package org.dromara.easyes.core.biz;
import lombok.Data;
+import java.util.List;
+
/**
* 索引相关参数
*
@@ -45,6 +47,10 @@ public class EsIndexParam {
* 字段是否忽略大小写,默认不忽略 为true时则忽略大小写
*/
private boolean ignoreCase;
+ /**
+ * 字段最大索引长度 默认256
+ */
+ private Integer ignoreAbove;
/**
* 父名称
*/
@@ -53,4 +59,35 @@ public class EsIndexParam {
* 子名称
*/
private String childName;
+ /**
+ * 内部字段列表
+ */
+ private List innerFieldParamList;
+
+ /**
+ * 内部段参数
+ */
+ @Data
+ public static class InnerFieldParam {
+ /**
+ * 内部字段名称
+ */
+ private String column;
+ /**
+ * 内部字段类型
+ */
+ private String fieldType;
+ /**
+ * 内部分词器
+ */
+ private String analyzer;
+ /**
+ * 内部查询分词器
+ */
+ private String searchAnalyzer;
+ /**
+ * 内部字段最大索引长度
+ */
+ private Integer ignoreAbove;
+ }
}
diff --git a/easy-es-core/src/main/java/org/dromara/easyes/core/config/GlobalConfig.java b/easy-es-core/src/main/java/org/dromara/easyes/core/config/GlobalConfig.java
index c99f4d0c..9d3f1388 100644
--- a/easy-es-core/src/main/java/org/dromara/easyes/core/config/GlobalConfig.java
+++ b/easy-es-core/src/main/java/org/dromara/easyes/core/config/GlobalConfig.java
@@ -5,7 +5,7 @@ import lombok.Data;
import org.dromara.easyes.annotation.rely.FieldStrategy;
import org.dromara.easyes.annotation.rely.IdType;
import org.dromara.easyes.common.enums.ProcessIndexStrategyEnum;
-import org.dromara.easyes.annotation.rely.RefreshPolicy;
+import org.dromara.easyes.common.enums.RefreshPolicy;
import org.springframework.boot.context.properties.NestedConfigurationProperty;
import static org.dromara.easyes.common.constants.BaseEsConstants.EMPTY_STR;
@@ -79,7 +79,7 @@ public class GlobalConfig {
*/
private boolean enableTrackTotalHits = true;
/**
- * data refresh policy 数据刷新策略,es默认的数据刷新策略为NONE
+ * data refresh policy 数据刷新策略,默认为NONE
*/
private RefreshPolicy refreshPolicy = RefreshPolicy.NONE;
/**
diff --git a/easy-es-core/src/main/java/org/dromara/easyes/core/core/BaseEsMapperImpl.java b/easy-es-core/src/main/java/org/dromara/easyes/core/core/BaseEsMapperImpl.java
index 3697ef93..6ebf53b2 100644
--- a/easy-es-core/src/main/java/org/dromara/easyes/core/core/BaseEsMapperImpl.java
+++ b/easy-es-core/src/main/java/org/dromara/easyes/core/core/BaseEsMapperImpl.java
@@ -13,7 +13,7 @@ import org.dromara.easyes.annotation.rely.IdType;
import org.dromara.easyes.common.constants.BaseEsConstants;
import org.dromara.easyes.common.enums.EsQueryTypeEnum;
import org.dromara.easyes.common.enums.MethodEnum;
-import org.dromara.easyes.annotation.rely.RefreshPolicy;
+import org.dromara.easyes.common.enums.RefreshPolicy;
import org.dromara.easyes.common.utils.*;
import org.dromara.easyes.core.biz.*;
import org.dromara.easyes.core.cache.BaseCache;
@@ -1485,7 +1485,7 @@ public class BaseEsMapperImpl implements BaseEsMapper {
&& searchResponse.getShardFailures() != null
&& searchResponse.getShardFailures().length > ZERO) {
String errorMsg = searchResponse.getShardFailures()[0].toString();
- throw ExceptionUtils.eee("es响应出错,search response failed ,failedShards: " + errorMsg);
+ throw ExceptionUtils.eee("search response failed ,failedShards: " + errorMsg);
}
}
@@ -1495,7 +1495,7 @@ public class BaseEsMapperImpl implements BaseEsMapper {
* @return 刷新策略
*/
private String getRefreshPolicy() {
- return EntityInfoHelper.getEntityInfo(entityClass).getRefreshPolicy().getValue();
+ return GlobalConfigCache.getGlobalConfig().getDbConfig().getRefreshPolicy().getValue();
}
/**
diff --git a/easy-es-core/src/main/java/org/dromara/easyes/core/toolkit/EntityInfoHelper.java b/easy-es-core/src/main/java/org/dromara/easyes/core/toolkit/EntityInfoHelper.java
index 427ed5bb..5eb8ee9d 100644
--- a/easy-es-core/src/main/java/org/dromara/easyes/core/toolkit/EntityInfoHelper.java
+++ b/easy-es-core/src/main/java/org/dromara/easyes/core/toolkit/EntityInfoHelper.java
@@ -8,11 +8,7 @@ import org.dromara.easyes.annotation.*;
import org.dromara.easyes.annotation.rely.DefaultNestedClass;
import org.dromara.easyes.annotation.rely.FieldType;
import org.dromara.easyes.annotation.rely.IdType;
-import org.dromara.easyes.annotation.rely.RefreshPolicy;
-import org.dromara.easyes.common.utils.ClassUtils;
-import org.dromara.easyes.common.utils.FastJsonUtils;
-import org.dromara.easyes.common.utils.ReflectionKit;
-import org.dromara.easyes.common.utils.StringUtils;
+import org.dromara.easyes.common.utils.*;
import org.dromara.easyes.core.biz.EntityFieldInfo;
import org.dromara.easyes.core.biz.EntityInfo;
import org.dromara.easyes.core.biz.HighLightParam;
@@ -106,14 +102,14 @@ public class EntityInfoHelper {
List list = getAllFields(clazz);
// 标记是否读取到主键
boolean isReadPK = false;
- // 是否存在 @TableId 注解
- boolean existTableId = isExistIndexId(list);
+ // 是否存在 @IndexId 注解
+ boolean existsIndexId = isExistIndexId(list);
List fieldList = new ArrayList<>();
for (Field field : list) {
// 主键ID 初始化
if (!isReadPK) {
- if (existTableId) {
+ if (existsIndexId) {
isReadPK = initIndexIdWithAnnotation(dbConfig, entityInfo, field);
} else {
isReadPK = initIndexIdWithoutAnnotation(dbConfig, entityInfo, field);
@@ -252,8 +248,8 @@ public class EntityInfoHelper {
Field field, EntityInfo entityInfo) {
boolean hasAnnotation = false;
- // 初始化封装IndexField注解信息
- if (field.isAnnotationPresent(IndexField.class)) {
+ // 初始化封装IndexField及MultiIndexField注解信息
+ if (field.isAnnotationPresent(IndexField.class) || field.isAnnotationPresent(MultiIndexField.class)) {
initIndexFieldAnnotation(dbConfig, entityInfo, field, fieldList);
hasAnnotation = true;
}
@@ -294,60 +290,73 @@ public class EntityInfoHelper {
*/
private static void initIndexFieldAnnotation(GlobalConfig.DbConfig dbConfig, EntityInfo entityInfo,
Field field, List fieldList) {
- IndexField tableField = field.getAnnotation(IndexField.class);
- if (tableField.exist()) {
+ MultiIndexField multiIndexField = field.getAnnotation(MultiIndexField.class);
+ IndexField indexField = Optional.ofNullable(multiIndexField).map(MultiIndexField::mainIndexField)
+ .orElse(field.getAnnotation(IndexField.class));
+ if (indexField.exist()) {
// 存在字段处理
- EntityFieldInfo entityFieldInfo = new EntityFieldInfo(dbConfig, field, tableField);
+ EntityFieldInfo entityFieldInfo = new EntityFieldInfo(dbConfig, field, indexField);
+
// 自定义字段名及驼峰下划线转换
String mappingColumn;
- if (!StringUtils.isBlank(tableField.value().trim())) {
+ if (!StringUtils.isBlank(indexField.value().trim())) {
// 自定义注解指定的名称优先级最高
- entityInfo.getMappingColumnMap().putIfAbsent(field.getName(), tableField.value());
- entityInfo.getColumnMappingMap().putIfAbsent(tableField.value(), field.getName());
- mappingColumn = tableField.value();
+ entityInfo.getMappingColumnMap().putIfAbsent(field.getName(), indexField.value());
+ entityInfo.getColumnMappingMap().putIfAbsent(indexField.value(), field.getName());
+ mappingColumn = indexField.value();
} else {
// 下划线驼峰
mappingColumn = initMappingColumnMapAndGet(dbConfig, entityInfo, field);
}
// 日期格式化
- if (StringUtils.isNotBlank(tableField.dateFormat())) {
- entityFieldInfo.setDateFormat(tableField.dateFormat());
+ if (StringUtils.isNotBlank(indexField.dateFormat())) {
+ entityFieldInfo.setDateFormat(indexField.dateFormat());
}
// 是否忽略大小写
- FieldType fieldType = FieldType.getByType(IndexUtils.getEsFieldType(tableField.fieldType(), field.getType().getSimpleName()));
+ FieldType fieldType = FieldType.getByType(IndexUtils.getEsFieldType(indexField.fieldType(), field.getType().getSimpleName()));
if (FieldType.KEYWORD.equals(fieldType)) {
// 仅对keyword类型设置,其它类型es不支持
- entityFieldInfo.setIgnoreCase(tableField.ignoreCase());
+ entityFieldInfo.setIgnoreCase(indexField.ignoreCase());
}
+
+ // 最大索引长度
+ if (indexField.ignoreAbove() > ZERO) {
+ entityFieldInfo.setIgnoreAbove(indexField.ignoreAbove());
+ }
+
// 其它
entityFieldInfo.setMappingColumn(mappingColumn);
- entityFieldInfo.setAnalyzer(tableField.analyzer());
- entityFieldInfo.setSearchAnalyzer(tableField.searchAnalyzer());
+ entityFieldInfo.setAnalyzer(indexField.analyzer());
+ entityFieldInfo.setSearchAnalyzer(indexField.searchAnalyzer());
entityFieldInfo.setFieldType(fieldType);
- entityFieldInfo.setFieldData(tableField.fieldData());
+ entityFieldInfo.setFieldData(indexField.fieldData());
entityFieldInfo.setColumnType(field.getType().getSimpleName());
entityInfo.getFieldTypeMap().putIfAbsent(field.getName(), fieldType.getType());
// 父子类型
- if (FieldType.JOIN.equals(tableField.fieldType())) {
- entityFieldInfo.setParentName(tableField.parentName());
- entityFieldInfo.setChildName(tableField.childName());
+ if (FieldType.JOIN.equals(indexField.fieldType())) {
+ entityFieldInfo.setParentName(indexField.parentName());
+ entityFieldInfo.setChildName(indexField.childName());
entityInfo.setJoinFieldName(mappingColumn);
- entityInfo.setJoinFieldClass(tableField.joinFieldClass());
- entityInfo.getPathClassMap().putIfAbsent(field.getName(), tableField.joinFieldClass());
- processNested(tableField.joinFieldClass(), dbConfig, entityInfo);
+ entityInfo.setJoinFieldClass(indexField.joinFieldClass());
+ entityInfo.getPathClassMap().putIfAbsent(field.getName(), indexField.joinFieldClass());
+ processNested(indexField.joinFieldClass(), dbConfig, entityInfo);
}
+ // 处理内部字段
+ InnerIndexField[] innerIndexFields = Optional.ofNullable(multiIndexField).map(MultiIndexField::otherIndexFields).orElse(null);
+ processInnerField(innerIndexFields, entityFieldInfo);
+
fieldList.add(entityFieldInfo);
// 嵌套类处理
- if (DefaultNestedClass.class != tableField.nestedClass()) {
+ if (DefaultNestedClass.class != indexField.nestedClass()) {
// 嵌套类
- entityInfo.getPathClassMap().putIfAbsent(field.getName(), tableField.nestedClass());
- processNested(tableField.nestedClass(), dbConfig, entityInfo);
+ entityInfo.getPathClassMap().putIfAbsent(field.getName(), indexField.nestedClass());
+ processNested(indexField.nestedClass(), dbConfig, entityInfo);
}
} else {
@@ -405,8 +414,10 @@ public class EntityInfoHelper {
String mappingColumn;
FieldType fieldType;
// 处理TableField注解
- IndexField tableField = field.getAnnotation(IndexField.class);
- if (Objects.isNull(tableField)) {
+ MultiIndexField multiIndexField = field.getAnnotation(MultiIndexField.class);
+ IndexField indexField = Optional.ofNullable(multiIndexField).map(MultiIndexField::mainIndexField)
+ .orElse(field.getAnnotation(IndexField.class));
+ if (Objects.isNull(indexField)) {
mappingColumn = getMappingColumn(dbConfig, field);
EntityFieldInfo entityFieldInfo = new EntityFieldInfo(dbConfig, field);
entityFieldInfo.setMappingColumn(mappingColumn);
@@ -415,36 +426,41 @@ public class EntityInfoHelper {
entityFieldInfo.setColumnType(field.getType().getSimpleName());
entityFieldInfoList.add(entityFieldInfo);
} else {
- if (tableField.exist()) {
+ if (indexField.exist()) {
// 子嵌套,递归处理
- if (DefaultNestedClass.class != tableField.nestedClass()) {
- entityInfo.getPathClassMap().putIfAbsent(field.getName(), tableField.nestedClass());
- processNested(tableField.nestedClass(), dbConfig, entityInfo);
+ if (DefaultNestedClass.class != indexField.nestedClass()) {
+ entityInfo.getPathClassMap().putIfAbsent(field.getName(), indexField.nestedClass());
+ processNested(indexField.nestedClass(), dbConfig, entityInfo);
}
// 字段名称
- if (StringUtils.isNotBlank(tableField.value().trim())) {
- mappingColumn = tableField.value();
+ if (StringUtils.isNotBlank(indexField.value().trim())) {
+ mappingColumn = indexField.value();
} else {
mappingColumn = getMappingColumn(dbConfig, field);
}
// 设置实体字段信息
- EntityFieldInfo entityFieldInfo = new EntityFieldInfo(dbConfig, field, tableField);
- fieldType = FieldType.NONE.equals(tableField.fieldType()) ? FieldType.KEYWORD_TEXT : tableField.fieldType();
+ EntityFieldInfo entityFieldInfo = new EntityFieldInfo(dbConfig, field, indexField);
+ fieldType = FieldType.NONE.equals(indexField.fieldType()) ? FieldType.KEYWORD_TEXT : indexField.fieldType();
entityFieldInfo.setMappingColumn(mappingColumn);
entityFieldInfo.setFieldType(fieldType);
- entityFieldInfo.setFieldData(tableField.fieldData());
+ entityFieldInfo.setFieldData(indexField.fieldData());
entityFieldInfo.setColumnType(fieldType.getType());
- entityFieldInfo.setAnalyzer(tableField.analyzer());
- entityFieldInfo.setSearchAnalyzer(tableField.searchAnalyzer());
+ entityFieldInfo.setAnalyzer(indexField.analyzer());
+ entityFieldInfo.setSearchAnalyzer(indexField.searchAnalyzer());
if (FieldType.KEYWORD.equals(fieldType)) {
// 仅对keyword类型设置,其它类型es不支持
- entityFieldInfo.setIgnoreCase(tableField.ignoreCase());
+ entityFieldInfo.setIgnoreCase(indexField.ignoreCase());
}
- if (StringUtils.isNotBlank(tableField.dateFormat())) {
- entityFieldInfo.setDateFormat(tableField.dateFormat());
+ if (StringUtils.isNotBlank(indexField.dateFormat())) {
+ entityFieldInfo.setDateFormat(indexField.dateFormat());
}
+
+ // 处理内部字段
+ InnerIndexField[] innerIndexFields = Optional.ofNullable(multiIndexField).map(MultiIndexField::otherIndexFields).orElse(null);
+ processInnerField(innerIndexFields, entityFieldInfo);
+
entityFieldInfoList.add(entityFieldInfo);
} else {
mappingColumn = getMappingColumn(dbConfig, field);
@@ -464,6 +480,31 @@ public class EntityInfoHelper {
entityInfo.getNestedFieldListMap().put(nestedClass, entityFieldInfoList);
}
+ /**
+ * 处理内部字段
+ *
+ * @param innerIndexFields 内部字段注解数组
+ * @param entityFieldInfo 内部字段信息
+ */
+ private static void processInnerField(InnerIndexField[] innerIndexFields, EntityFieldInfo entityFieldInfo) {
+ if (ArrayUtils.isNotEmpty(innerIndexFields)) {
+ List innerFieldInfoList = new ArrayList<>();
+ Arrays.stream(innerIndexFields).forEach(innerField -> {
+ Assert.notBlank(innerField.suffix(), "The Annotation MultiIndexField.InnerIndexField.value must has text");
+ EntityFieldInfo.InnerFieldInfo innerFieldInfo = new EntityFieldInfo.InnerFieldInfo();
+ innerFieldInfo.setColumn(innerField.suffix());
+ innerFieldInfo.setFieldType(innerField.fieldType());
+ innerFieldInfo.setAnalyzer(innerField.analyzer());
+ innerFieldInfo.setSearchAnalyzer(innerField.searchAnalyzer());
+ if (innerField.ignoreAbove() > 0){
+ innerFieldInfo.setIgnoreAbove(innerField.ignoreAbove());
+ }
+ innerFieldInfoList.add(innerFieldInfo);
+ });
+ entityFieldInfo.setInnerFieldInfoList(innerFieldInfoList);
+ }
+ }
+
/**
* 字段属性初始化
@@ -617,12 +658,6 @@ public class EntityInfoHelper {
entityInfo.setReplicasNum(table.replicasNum());
entityInfo.setChild(table.child());
entityInfo.setChildClass(table.childClass());
-
- RefreshPolicy refreshPolicy = table.refreshPolicy();
- if (RefreshPolicy.GLOBAL.equals(refreshPolicy)) {
- refreshPolicy = dbConfig.getRefreshPolicy();
- }
- entityInfo.setRefreshPolicy(refreshPolicy);
}
String targetIndexName = indexName;
diff --git a/easy-es-core/src/main/java/org/dromara/easyes/core/toolkit/IndexUtils.java b/easy-es-core/src/main/java/org/dromara/easyes/core/toolkit/IndexUtils.java
index b923c51e..9be2800f 100644
--- a/easy-es-core/src/main/java/org/dromara/easyes/core/toolkit/IndexUtils.java
+++ b/easy-es-core/src/main/java/org/dromara/easyes/core/toolkit/IndexUtils.java
@@ -59,20 +59,14 @@ import static org.dromara.easyes.common.constants.BaseEsConstants.*;
public class IndexUtils {
private static final String FIELDS_KEY;
- private static final Map FIELDS_MAP;
- private static final int IGNORE_ABOVE;
+ private static final int DEFAULT_IGNORE_ABOVE;
private static final String IGNORE_ABOVE_KEY;
static {
- FIELDS_MAP = new HashMap<>();
FIELDS_KEY = "fields";
- IGNORE_ABOVE = 256;
+ DEFAULT_IGNORE_ABOVE = 256;
IGNORE_ABOVE_KEY = "ignore_above";
- Map keywordsMap = new HashMap<>();
- keywordsMap.put(TYPE, FieldType.KEYWORD.getType());
- keywordsMap.put(IGNORE_ABOVE_KEY, IGNORE_ABOVE);
- FIELDS_MAP.put(FieldType.KEYWORD.getType(), keywordsMap);
}
/**
@@ -323,7 +317,7 @@ public class IndexUtils {
return fieldType.getType();
}
- // 否则根据类型推断,String以及找不到的类型一律被当做keyword处理
+ // 否则根据类型推断,String以及找不到的类型一律被当做keyword_text复核类型处理
JdkDataTypeEnum jdkDataType = JdkDataTypeEnum.getByType(typeName.toLowerCase());
String type;
switch (jdkDataType) {
@@ -414,9 +408,17 @@ public class IndexUtils {
}
// 设置type
+ Map fieldsMap = null;
if (FieldType.KEYWORD_TEXT.getType().equals(indexParam.getFieldType())) {
+ // 复合类型需特殊处理
info.put(BaseEsConstants.TYPE, FieldType.TEXT.getType());
- info.put(FIELDS_KEY, FIELDS_MAP);
+ fieldsMap = new HashMap<>();
+ Map keywordMap = new HashMap<>();
+ keywordMap.put(TYPE, FieldType.KEYWORD.getType());
+ int ignoreAbove = Optional.ofNullable(indexParam.getIgnoreAbove()).orElse(DEFAULT_IGNORE_ABOVE);
+ keywordMap.put(IGNORE_ABOVE_KEY, ignoreAbove);
+ fieldsMap.put(FieldType.KEYWORD.getType(), keywordMap);
+ info.put(FIELDS_KEY, fieldsMap);
} else {
info.put(BaseEsConstants.TYPE, indexParam.getFieldType());
}
@@ -427,11 +429,10 @@ public class IndexUtils {
if (containsTextType) {
// 设置分词器
Optional.ofNullable(indexParam.getAnalyzer())
- .ifPresent(analyzer ->
- info.put(BaseEsConstants.ANALYZER, indexParam.getAnalyzer().toLowerCase()));
+ .ifPresent(analyzer -> info.put(BaseEsConstants.ANALYZER, analyzer.toLowerCase()));
Optional.ofNullable(indexParam.getSearchAnalyzer())
.ifPresent(searchAnalyzer ->
- info.put(BaseEsConstants.SEARCH_ANALYZER, indexParam.getSearchAnalyzer().toLowerCase()));
+ info.put(BaseEsConstants.SEARCH_ANALYZER, searchAnalyzer.toLowerCase()));
// 设置是否对text类型进行聚合处理
MyOptional.ofNullable(indexParam.getFieldData()).ifTrue(fieldData -> info.put(FIELD_DATA, fieldData));
@@ -462,6 +463,31 @@ public class IndexUtils {
if (dbConfig.isMapUnderscoreToCamelCase()) {
fieldName = StringUtils.camelToUnderline(fieldName);
}
+
+ // 设置内部字段
+ if (CollectionUtils.isNotEmpty(indexParam.getInnerFieldParamList())) {
+ Map finalFieldsMap = Optional.ofNullable(fieldsMap).orElseGet(HashMap::new);
+ indexParam.getInnerFieldParamList().forEach(innerFieldParam -> {
+ Map innerInfo = new HashMap<>();
+ if (FieldType.KEYWORD_TEXT.getType().equals(innerFieldParam.getFieldType())) {
+ ExceptionUtils.eee("The fieldType FieldType.KEYWORD_TEXT just for mainIndexField, can not be used in @InnerIndexField");
+ }
+ innerInfo.put(TYPE, innerFieldParam.getFieldType());
+ boolean innerContainsTextType = FieldType.TEXT.getType().equals(innerFieldParam.getFieldType()) ||
+ FieldType.KEYWORD_TEXT.getType().equals(innerFieldParam.getFieldType());
+ if (innerContainsTextType) {
+ Optional.ofNullable(innerFieldParam.getAnalyzer()).ifPresent(i -> innerInfo.put(ANALYZER, i));
+ Optional.ofNullable(innerFieldParam.getSearchAnalyzer())
+ .ifPresent(i -> innerInfo.put(SEARCH_ANALYZER, i));
+ }
+ Optional.ofNullable(innerFieldParam.getIgnoreAbove())
+ .ifPresent(i -> innerInfo.put(IGNORE_ABOVE_KEY, innerFieldParam.getIgnoreAbove()));
+ finalFieldsMap.putIfAbsent(innerFieldParam.getColumn(), innerInfo);
+ });
+
+ info.put(FIELDS_KEY, finalFieldsMap);
+ }
+
properties.put(fieldName, info);
});
return properties;
@@ -589,6 +615,25 @@ public class IndexUtils {
esIndexParam.setIgnoreCase(field.isIgnoreCase());
Optional.ofNullable(field.getParentName()).ifPresent(esIndexParam::setParentName);
Optional.ofNullable(field.getChildName()).ifPresent(esIndexParam::setChildName);
+
+ // 内部字段处理
+ final List innerFieldInfoList = field.getInnerFieldInfoList();
+ if (CollectionUtils.isNotEmpty(innerFieldInfoList)) {
+ List innerFieldParamList = new ArrayList<>();
+ innerFieldInfoList.forEach(innerFieldInfo -> {
+ EsIndexParam.InnerFieldParam innerFieldParam = new EsIndexParam.InnerFieldParam();
+ innerFieldParam.setColumn(innerFieldInfo.getColumn());
+ if (!Analyzer.NONE.equals(innerFieldInfo.getAnalyzer())) {
+ innerFieldParam.setAnalyzer(innerFieldInfo.getAnalyzer());
+ }
+ if (!Analyzer.NONE.equals(innerFieldInfo.getSearchAnalyzer())) {
+ innerFieldParam.setSearchAnalyzer(innerFieldInfo.getSearchAnalyzer());
+ }
+ innerFieldParam.setFieldType(innerFieldInfo.getFieldType().getType());
+ innerFieldParamList.add(innerFieldParam);
+ });
+ esIndexParam.setInnerFieldParamList(innerFieldParamList);
+ }
esIndexParamList.add(esIndexParam);
});
}
diff --git a/easy-es-test/src/main/java/org/dromara/easyes/test/entity/Document.java b/easy-es-test/src/main/java/org/dromara/easyes/test/entity/Document.java
index 4e43d87d..a129c64d 100644
--- a/easy-es-test/src/main/java/org/dromara/easyes/test/entity/Document.java
+++ b/easy-es-test/src/main/java/org/dromara/easyes/test/entity/Document.java
@@ -5,7 +5,6 @@ import lombok.Data;
import lombok.experimental.Accessors;
import org.dromara.easyes.annotation.*;
import org.dromara.easyes.annotation.rely.*;
-import org.dromara.easyes.annotation.rely.RefreshPolicy;
import java.util.List;
@@ -16,9 +15,7 @@ import java.util.List;
**/
@Data
@Accessors(chain = true)
-@IndexName(value = "easyes_document", shardsNum = 3, replicasNum = 2,
- keepGlobalPrefix = true, childClass = Comment.class, routing = "testRouting",
- refreshPolicy = RefreshPolicy.IMMEDIATE)
+@IndexName(value = "easyes_document", shardsNum = 3, replicasNum = 2, keepGlobalPrefix = true, childClass = Comment.class, routing = "testRouting")
public class Document {
/**
* es中的唯一id,字段名随便起,我这里演示用esId,你也可以用id(推荐),bizId等.
@@ -126,4 +123,16 @@ public class Document {
*/
@Distance(decimalPlaces = 2)
private Double distance2;
+
+ /**
+ * 复合字段,此注解和SpringData中的MultiField用法类似 适用于对同一个字段通过多种分词器检索的场景
+ */
+ @MultiIndexField(mainIndexField = @IndexField(fieldType = FieldType.KEYWORD),
+ otherIndexFields = {@InnerIndexField(suffix = "zh", fieldType = FieldType.TEXT, analyzer = Analyzer.IK_SMART),
+ @InnerIndexField(suffix = "pinyin", fieldType = FieldType.TEXT, analyzer = "pinyin")})
+ private String multiField;
+ /**
+ * 英文名
+ */
+ private String english;
}
diff --git a/easy-es-test/src/test/java/org/dromara/easyes/test/all/AllTest.java b/easy-es-test/src/test/java/org/dromara/easyes/test/all/AllTest.java
index a464c1ad..cc60de82 100644
--- a/easy-es-test/src/test/java/org/dromara/easyes/test/all/AllTest.java
+++ b/easy-es-test/src/test/java/org/dromara/easyes/test/all/AllTest.java
@@ -85,6 +85,8 @@ public class AllTest {
Rectangle rectangle = new Rectangle(39.084509D, 41.187328D, 70.610461D, 20.498353D);
document.setGeoLocation(rectangle.toString());
document.setStarNum(1);
+ document.setMultiField("葡萄糖酸钙口服溶液");
+ document.setEnglish("Calcium Gluconate");
int successCount = documentMapper.insert(document);
Assertions.assertEquals(successCount, 1);
@@ -880,6 +882,21 @@ public class AllTest {
Assertions.assertEquals(22, documents.size());
}
+ @Test
+ @Order(6)
+ public void testMultiFieldSelect() {
+ // 药品 中文名叫葡萄糖酸钙口服溶液 英文名叫 Calcium Gluconate 汉语拼音为 putaotangsuangaikoufurongye
+ // 用户可以通过模糊检索,例如输入 Calcium 或 葡萄糖 或 putaotang时对应药品均可以被检索到
+ LambdaEsQueryWrapper wrapper = new LambdaEsQueryWrapper<>();
+ wrapper.match("english", "Calcium")
+ .or()
+ .match("multi_field.zh", "葡萄糖")
+ .or()
+ .match("multi_field.pinyin", "putaotang");
+ List documents = documentMapper.selectList(wrapper);
+ System.out.println(documents);
+ }
+
// 4.删除
@Test
@Order(7)
@@ -939,4 +956,5 @@ public class AllTest {
documentMapper.selectList(wrapper);
}
+
}