增加对text类型fieldData设置,设置后可支持text类型字段的聚合 此功能有Roin,码云ID:花落陌贡献 代码冲突和发1.0版本求稳等原因,暂由作者代提交

This commit is contained in:
xpc1024 2022-08-19 11:12:52 +08:00
parent 6b6a0311b9
commit ba7708db61
10 changed files with 159 additions and 21 deletions

View File

@ -40,6 +40,13 @@ public @interface IndexField {
*/ */
FieldType fieldType() default FieldType.NONE; FieldType fieldType() default FieldType.NONE;
/**
* 设置textkeyword_text 可以进行聚合操作
*
* @return 是否设置可聚合
*/
boolean fieldData() default false;
/** /**
* 索引文档时用的分词器 * 索引文档时用的分词器
* *

View File

@ -226,5 +226,9 @@ public interface BaseEsConstants {
* 高亮截取默认长度 * 高亮截取默认长度
*/ */
int DEFAULT_FRAGMENT_SIZE = 100; int DEFAULT_FRAGMENT_SIZE = 100;
/**
* 针对text进行聚合
*/
String FIELD_DATA = "fielddata";
} }

View File

@ -39,6 +39,10 @@ public class EntityFieldInfo {
* 自动在es中的存储类型 * 自动在es中的存储类型
*/ */
private FieldType fieldType; private FieldType fieldType;
/**
* 设置textkeyword_text 可以进行聚合操作
*/
private boolean fieldData;
/** /**
* 分词器 * 分词器
*/ */

View File

@ -21,6 +21,10 @@ public class EsIndexParam {
* 字段类型 * 字段类型
*/ */
private String fieldType; private String fieldType;
/**
* text 字段进行聚合处理
*/
private Boolean fieldData;
/** /**
* 分词器 * 分词器
*/ */

View File

@ -110,8 +110,8 @@ public class LambdaEsIndexWrapper<T> extends Wrapper<T> implements Index<LambdaE
} }
@Override @Override
public LambdaEsIndexWrapper<T> mapping(String column, FieldType fieldType, String analyzer, String searchAnalyzer, String dateFormat, Float boost) { public LambdaEsIndexWrapper<T> mapping(String column, FieldType fieldType, String analyzer, String searchAnalyzer, String dateFormat, Boolean fieldData, Float boost) {
addEsIndexParam(column, fieldType, analyzer, analyzer, dateFormat, boost); addEsIndexParam(column, fieldType, analyzer, analyzer, dateFormat, fieldData, boost);
return typedThis; return typedThis;
} }
@ -138,13 +138,14 @@ public class LambdaEsIndexWrapper<T> extends Wrapper<T> implements Index<LambdaE
return typedThis; return typedThis;
} }
private void addEsIndexParam(String fieldName, FieldType fieldType, String analyzer, String searchAnalyzer, String dateFormat, Float boost) { private void addEsIndexParam(String fieldName, FieldType fieldType, String analyzer, String searchAnalyzer, String dateFormat, Boolean fieldData, Float boost) {
EsIndexParam esIndexParam = new EsIndexParam(); EsIndexParam esIndexParam = new EsIndexParam();
esIndexParam.setFieldName(fieldName); esIndexParam.setFieldName(fieldName);
esIndexParam.setFieldType(fieldType.getType()); esIndexParam.setFieldType(fieldType.getType());
esIndexParam.setAnalyzer(analyzer); esIndexParam.setAnalyzer(analyzer);
esIndexParam.setSearchAnalyzer(searchAnalyzer); esIndexParam.setSearchAnalyzer(searchAnalyzer);
esIndexParam.setDateFormat(dateFormat); esIndexParam.setDateFormat(dateFormat);
esIndexParam.setFieldData(fieldData);
esIndexParam.setBoost(boost); esIndexParam.setBoost(boost);
esIndexParamList.add(esIndexParam); esIndexParamList.add(esIndexParam);
} }

View File

@ -1,6 +1,5 @@
package cn.easyes.core.conditions.interfaces; package cn.easyes.core.conditions.interfaces;
import cn.easyes.common.constants.BaseEsConstants;
import cn.easyes.common.enums.FieldType; import cn.easyes.common.enums.FieldType;
import cn.easyes.core.toolkit.FieldUtils; import cn.easyes.core.toolkit.FieldUtils;
import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.Settings;
@ -49,27 +48,35 @@ public interface Index<Children, R> extends Serializable {
default Children mapping(R column, FieldType fieldType) { default Children mapping(R column, FieldType fieldType) {
return mapping(column, fieldType, null, null, null, null); return mapping(column, fieldType, null, null, null, null, null);
}
default Children mapping(R column, FieldType fieldType, Boolean fieldData) {
return mapping(column, fieldType, null, null, null, fieldData, null);
} }
default Children mapping(R column, FieldType fieldType, Float boost) { default Children mapping(R column, FieldType fieldType, Float boost) {
return mapping(column, fieldType, null, null, null, boost); return mapping(column, fieldType, null, null, null, null, boost);
}
default Children mapping(R column, FieldType fieldType, Boolean fieldData, Float boost) {
return mapping(column, fieldType, null, null, null, fieldData, boost);
} }
default Children mapping(R column, FieldType fieldType, String dateFormat) { default Children mapping(R column, FieldType fieldType, String dateFormat) {
return mapping(column, fieldType, null, null, dateFormat, null); return mapping(column, fieldType, null, null, dateFormat, null, null);
} }
default Children mapping(R column, FieldType fieldType, String analyzer, String searchAnalyzer) { default Children mapping(R column, FieldType fieldType, String analyzer, String searchAnalyzer) {
return mapping(column, fieldType, analyzer, searchAnalyzer, null, null); return mapping(column, fieldType, analyzer, searchAnalyzer, null, null, null);
} }
default Children mapping(R column, FieldType fieldType, String analyzer, String searchAnalyzer, String dateFormat) { default Children mapping(R column, FieldType fieldType, String analyzer, String searchAnalyzer, String dateFormat) {
return mapping(column, fieldType, analyzer, searchAnalyzer, dateFormat, null); return mapping(column, fieldType, analyzer, searchAnalyzer, dateFormat, null, null);
} }
default Children mapping(R column, FieldType fieldType, String analyzer, String searchAnalyzer, Float boost) { default Children mapping(R column, FieldType fieldType, String analyzer, String searchAnalyzer, Float boost) {
return mapping(column, fieldType, analyzer, searchAnalyzer, null, boost); return mapping(column, fieldType, analyzer, searchAnalyzer, null, null, boost);
} }
/** /**
@ -80,16 +87,21 @@ public interface Index<Children, R> extends Serializable {
* @param analyzer 分词器类型 * @param analyzer 分词器类型
* @param searchAnalyzer 查询分词器类型 * @param searchAnalyzer 查询分词器类型
* @param dateFormat 日期格式 * @param dateFormat 日期格式
* @param fieldData 是否支持text字段聚合
* @param boost 权重值 * @param boost 权重值
* @return 泛型 * @return 泛型
*/ */
default Children mapping(R column, FieldType fieldType, String analyzer, String searchAnalyzer, String dateFormat, Float boost) { default Children mapping(R column, FieldType fieldType, String analyzer, String searchAnalyzer, String dateFormat, Boolean fieldData, Float boost) {
return mapping(FieldUtils.getFieldName(column), fieldType, analyzer, searchAnalyzer, dateFormat, boost); return mapping(FieldUtils.getFieldName(column), fieldType, analyzer, searchAnalyzer, dateFormat, fieldData, boost);
} }
default Children mapping(String column, FieldType fieldType) { default Children mapping(String column, FieldType fieldType) {
return mapping(column, fieldType, null, null, null, null); return mapping(column, fieldType, null, null, null);
}
default Children mapping(String column, FieldType fieldType, Boolean fieldData) {
return mapping(column, fieldType, null, null, fieldData, null);
} }
default Children mapping(String column, FieldType fieldType, Float boost) { default Children mapping(String column, FieldType fieldType, Float boost) {
@ -98,17 +110,22 @@ public interface Index<Children, R> extends Serializable {
default Children mapping(String column, FieldType fieldType, String analyzer) { default Children mapping(String column, FieldType fieldType, String analyzer) {
return mapping(column, fieldType, analyzer, null, null, null); return mapping(column, fieldType, analyzer, null, null);
} }
default Children mapping(String column, FieldType fieldType, String analyzer, String searchAnalyzer) { default Children mapping(String column, FieldType fieldType, String analyzer, String searchAnalyzer) {
return mapping(column, fieldType, analyzer, searchAnalyzer, BaseEsConstants.DEFAULT_BOOST); return mapping(column, fieldType, analyzer, searchAnalyzer, null);
} }
default Children mapping(String column, FieldType fieldType, String analyzer, String searchAnalyzer, Float boost) { default Children mapping(String column, FieldType fieldType, String analyzer, String searchAnalyzer, Boolean fieldData) {
return mapping(column, fieldType, analyzer, searchAnalyzer, null, boost); return mapping(column, fieldType, analyzer, searchAnalyzer, fieldData, null);
} }
default Children mapping(String column, FieldType fieldType, String analyzer, String searchAnalyzer, Boolean fieldData, Float boost) {
return mapping(column, fieldType, analyzer, searchAnalyzer, null, fieldData, boost);
}
/** /**
* 设置mapping信息 * 设置mapping信息
* *
@ -117,10 +134,11 @@ public interface Index<Children, R> extends Serializable {
* @param analyzer 分词器类型 * @param analyzer 分词器类型
* @param searchAnalyzer 查询分词器类型 * @param searchAnalyzer 查询分词器类型
* @param dateFormat 日期格式 * @param dateFormat 日期格式
* @param fieldData 是否支持text字段聚合
* @param boost 字段权重值 * @param boost 字段权重值
* @return 泛型 * @return 泛型
*/ */
Children mapping(String column, FieldType fieldType, String analyzer, String searchAnalyzer, String dateFormat, Float boost); Children mapping(String column, FieldType fieldType, String analyzer, String searchAnalyzer, String dateFormat, Boolean fieldData, Float boost);
/** /**
* 设置创建别名信息 * 设置创建别名信息

View File

@ -320,6 +320,7 @@ public class EntityInfoHelper {
entityFieldInfo.setAnalyzer(tableField.analyzer()); entityFieldInfo.setAnalyzer(tableField.analyzer());
entityFieldInfo.setSearchAnalyzer(tableField.searchAnalyzer()); entityFieldInfo.setSearchAnalyzer(tableField.searchAnalyzer());
entityFieldInfo.setFieldType(tableField.fieldType()); entityFieldInfo.setFieldType(tableField.fieldType());
entityFieldInfo.setFieldData(tableField.fieldData());
entityFieldInfo.setColumnType(field.getType().getSimpleName()); entityFieldInfo.setColumnType(field.getType().getSimpleName());
// 父子类型 // 父子类型
@ -422,6 +423,7 @@ public class EntityInfoHelper {
entityFieldInfo.setMappingColumn(mappingColumn); entityFieldInfo.setMappingColumn(mappingColumn);
FieldType fieldType = FieldType.NESTED.equals(tableField.fieldType()) ? FieldType.NESTED : FieldType.TEXT; FieldType fieldType = FieldType.NESTED.equals(tableField.fieldType()) ? FieldType.NESTED : FieldType.TEXT;
entityFieldInfo.setFieldType(fieldType); entityFieldInfo.setFieldType(fieldType);
entityFieldInfo.setFieldData(tableField.fieldData());
entityFieldInfo.setColumnType(fieldType.getType()); entityFieldInfo.setColumnType(fieldType.getType());
entityFieldInfo.setAnalyzer(tableField.analyzer()); entityFieldInfo.setAnalyzer(tableField.analyzer());
entityFieldInfo.setSearchAnalyzer(tableField.searchAnalyzer()); entityFieldInfo.setSearchAnalyzer(tableField.searchAnalyzer());

View File

@ -381,16 +381,21 @@ public class IndexUtils {
info.put(BaseEsConstants.TYPE, indexParam.getFieldType()); info.put(BaseEsConstants.TYPE, indexParam.getFieldType());
} }
// 设置分词器 // 是否text类型或keyword_text类型
boolean needAnalyzer = FieldType.TEXT.getType().equals(indexParam.getFieldType()) || boolean containsTextType = FieldType.TEXT.getType().equals(indexParam.getFieldType()) ||
FieldType.KEYWORD_TEXT.getType().equals(indexParam.getFieldType()); FieldType.KEYWORD_TEXT.getType().equals(indexParam.getFieldType());
if (needAnalyzer) { if (containsTextType) {
// 设置分词器
Optional.ofNullable(indexParam.getAnalyzer()) Optional.ofNullable(indexParam.getAnalyzer())
.ifPresent(analyzer -> .ifPresent(analyzer ->
info.put(BaseEsConstants.ANALYZER, indexParam.getAnalyzer().toLowerCase())); info.put(BaseEsConstants.ANALYZER, indexParam.getAnalyzer().toLowerCase()));
Optional.ofNullable(indexParam.getSearchAnalyzer()) Optional.ofNullable(indexParam.getSearchAnalyzer())
.ifPresent(searchAnalyzer -> .ifPresent(searchAnalyzer ->
info.put(BaseEsConstants.SEARCH_ANALYZER, indexParam.getSearchAnalyzer().toLowerCase())); info.put(BaseEsConstants.SEARCH_ANALYZER, indexParam.getSearchAnalyzer().toLowerCase()));
// 设置是否对text类型进行聚合处理
Optional.ofNullable(indexParam.getFieldData())
.ifPresent(fieldData -> info.put(FIELD_DATA, indexParam.getFieldData()));
} }
// 设置权重 // 设置权重
@ -529,6 +534,7 @@ public class IndexUtils {
EsIndexParam esIndexParam = new EsIndexParam(); EsIndexParam esIndexParam = new EsIndexParam();
String esFieldType = IndexUtils.getEsFieldType(field.getFieldType(), field.getColumnType()); String esFieldType = IndexUtils.getEsFieldType(field.getFieldType(), field.getColumnType());
esIndexParam.setFieldType(esFieldType); esIndexParam.setFieldType(esFieldType);
esIndexParam.setFieldData(field.isFieldData());
esIndexParam.setFieldName(field.getMappingColumn()); esIndexParam.setFieldName(field.getMappingColumn());
esIndexParam.setDateFormat(field.getDateFormat()); esIndexParam.setDateFormat(field.getDateFormat());
if (FieldType.NESTED.equals(field.getFieldType())) { if (FieldType.NESTED.equals(field.getFieldType())) {

View File

@ -45,6 +45,11 @@ public class Document {
*/ */
@IndexField(strategy = FieldStrategy.NOT_EMPTY, fieldType = FieldType.KEYWORD_TEXT, analyzer = Analyzer.IK_SMART) @IndexField(strategy = FieldStrategy.NOT_EMPTY, fieldType = FieldType.KEYWORD_TEXT, analyzer = Analyzer.IK_SMART)
private String creator; private String creator;
/**
* 可以聚合的text类型,字段名字随便取,注解中指定fieldData=true后text类型也可以支持聚合
*/
@IndexField(fieldType = FieldType.TEXT, fieldData = true)
private String filedData;
/** /**
* 创建时间 * 创建时间
*/ */

View File

@ -0,0 +1,87 @@
package cn.easyes.test.other;
import cn.easyes.common.constants.BaseEsConstants;
import cn.easyes.common.enums.FieldType;
import cn.easyes.core.conditions.LambdaEsIndexWrapper;
import cn.easyes.core.conditions.LambdaEsQueryWrapper;
import cn.easyes.core.toolkit.EntityInfoHelper;
import cn.easyes.core.toolkit.EsWrappers;
import cn.easyes.test.TestEasyEsApplication;
import cn.easyes.test.entity.Document;
import cn.easyes.test.mapper.DocumentMapper;
import org.elasticsearch.geometry.Rectangle;
import org.junit.jupiter.api.*;
import org.springframework.boot.test.context.SpringBootTest;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
/**
* fieldData 创建索引测试
*
* @author dys
* @since 1.0
*/
@DisplayName("fieldData测试")
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
@SpringBootTest(classes = TestEasyEsApplication.class)
public class FieldDataTest {
@Resource
private DocumentMapper documentMapper;
/**
* 测试自动创建索引并插入数据
*/
@Test
@Order(1)
void testAutoCreateIndex() {
// 测试插入数据
Document document = new Document();
document.setEsId("1");
document.setTitle("测试文档1");
document.setContent("测试内容1");
document.setCreator("老汉1");
document.setLocation("40.171975,116.587105");
document.setGmtCreate(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
document.setCustomField("自定义字段1");
document.setNullField("id为1的数据不是null,除此之外其它都是");
Rectangle rectangle = new Rectangle(39.084509D, 41.187328D, 70.610461D, 20.498353D);
document.setGeoLocation(rectangle.toString());
document.setStarNum(1);
document.setFiledData("123");
int successCount = documentMapper.insert(document);
Assertions.assertEquals(successCount, 1);
LambdaEsQueryWrapper<Document> lambdaEsQueryWrapper = EsWrappers.lambdaQuery(Document.class)
.matchAllQuery()
// 设置为如果filedData为false 或不设置 text类型排序会报错
.orderByDesc(Document::getFiledData);
List<Document> documents = documentMapper.selectList(lambdaEsQueryWrapper);
Assertions.assertEquals(documents.size(), 1);
}
/**
* 测试手动创建索引配置是否生效
*/
@Test
@Order(2)
void testFiledData() {
LambdaEsIndexWrapper<Document> wrapper = EsWrappers.lambdaIndex(Document.class)
.indexName("document1")
.mapping(Document::getTitle, FieldType.TEXT, true);
Boolean index = documentMapper.createIndex(wrapper);
Assertions.assertTrue(index);
}
@Test
@Order(3)
public void testDeleteIndex() {
Boolean dcoument1 = documentMapper.deleteIndex("document1");
boolean deleted = documentMapper.deleteIndex(EntityInfoHelper.getEntityInfo(Document.class).getIndexName());
boolean lockDeleted = documentMapper.deleteIndex(BaseEsConstants.LOCK_INDEX);
Assertions.assertTrue(dcoument1);
Assertions.assertTrue(deleted);
Assertions.assertTrue(lockDeleted);
}
}