mirror of
https://gitee.com/dromara/easy-es.git
synced 2025-12-06 17:18:57 +08:00
v2.0.0-beta5
1.嵌套类型支持高亮注解 2.增加小黑子趣味debug模式 3.修复已知缺陷 4.持续更新中...
This commit is contained in:
parent
db8c94495e
commit
095a7bb2b2
@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.dromara.easy-es</groupId>
|
||||
<artifactId>easy-es-parent</artifactId>
|
||||
<version>2.0.0-beta4</version>
|
||||
<version>2.0.0-beta5</version>
|
||||
<relativePath>../easy-es-parent</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@ -9,7 +9,7 @@ import java.util.Arrays;
|
||||
**/
|
||||
public enum FieldType {
|
||||
/**
|
||||
* none Required inside the framework, do not use 框架内部需要,切勿使用,若不慎使用则会被当做keyword&text类型
|
||||
* none Required inside the framework, do not use 框架内部需要,切勿使用,若不慎使用则会被当做keyword_text类型
|
||||
*/
|
||||
NONE("none"),
|
||||
/**
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>org.dromara.easy-es</groupId>
|
||||
<artifactId>easy-es-parent</artifactId>
|
||||
<version>2.0.0-beta4</version>
|
||||
<version>2.0.0-beta5</version>
|
||||
<relativePath>../easy-es-parent</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@ -18,8 +18,7 @@ import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.dromara.easyes.common.constants.BaseEsConstants.ENABLE_BANNER;
|
||||
import static org.dromara.easyes.common.constants.BaseEsConstants.ENABLE_PREFIX;
|
||||
import static org.dromara.easyes.common.constants.BaseEsConstants.*;
|
||||
|
||||
/**
|
||||
* 注册bean
|
||||
@ -46,19 +45,50 @@ public class MapperScannerRegister implements ImportBeanDefinitionRegistrar, Res
|
||||
//打印banner @author dazer007
|
||||
boolean banner = Optional.ofNullable(environment.getProperty(ENABLE_BANNER)).map(Boolean::parseBoolean).orElse(Boolean.TRUE);
|
||||
if (banner) {
|
||||
boolean iKunMode = Optional.ofNullable(environment.getProperty(ENABLE_I_KUN_MODE)).map(Boolean::parseBoolean).orElse(Boolean.FALSE);
|
||||
String versionStr = EEVersionUtils.getJarVersion(this.getClass());
|
||||
System.out.println("\n" +
|
||||
"___ _ _ ___\n" +
|
||||
" | __| __ _ ___ | || | ___ | __| ___\n" +
|
||||
" | _| / _` | (_-< \\_, | |___| | _| (_-<\n" +
|
||||
" |___| \\__,_| /__/_ _|__/ _____ |___| /__/_\n" +
|
||||
"_|\"\"\"\"\"|_|\"\"\"\"\"|_|\"\"\"\"\"|_| \"\"\"\"|_| |_|\"\"\"\"\"|_|\"\"\"\"\"|\n" +
|
||||
"\"`-0-0-'\"`-0-0-'\"`-0-0-'\"`-0-0-'\"`-0-0-'\"`-0-0-'\"`-0-0-'\n" +
|
||||
"------------------------------------------------------>"
|
||||
);
|
||||
String wechatStr = ":: wechat :: 252645816, add and become muscle man! >";
|
||||
if (iKunMode) {
|
||||
System.out.println(" 鸡你太美\n" +
|
||||
" 鸡你实在太美\n" +
|
||||
" 鸡你是太美\n" +
|
||||
" 鸡你太美\n" +
|
||||
" 实在是太美鸡你\n" +
|
||||
" 鸡你 实在是太美鸡你 美\n" +
|
||||
" 鸡你 实在是太美鸡美 太美\n" +
|
||||
" 鸡你 实在是太美鸡美 太美\n" +
|
||||
" 鸡你 实在是太美鸡美 太美\n" +
|
||||
" 鸡你 鸡你实在是美太美 美蓝球球球\n" +
|
||||
"鸡 鸡 鸡你实在是太美 篮球篮球球球球\n" +
|
||||
" 鸡 鸡你太美裆鸡太啊 球球蓝篮球球\n" +
|
||||
" 鸡你太美裆裆鸡美 球球球\n" +
|
||||
" 鸡你裆小 j 鸡太美\n" +
|
||||
" 鸡太美 鸡太美\n" +
|
||||
" 鸡美 鸡美\n" +
|
||||
" 鸡美 鸡美\n" +
|
||||
" 鸡美 鸡美\n" +
|
||||
" 鸡太 鸡太\n" +
|
||||
" 鸡 脚 鸡脚\n" +
|
||||
" 皮 鞋 皮鞋金猴\n" +
|
||||
" 金光 金光 大道\n" +
|
||||
" 大道\n" +
|
||||
" 鸡神保佑 永不宕机 永无BUG");
|
||||
wechatStr = ":: wechat :: 252645816, add and join ikun(小黑子) group! >";
|
||||
} else {
|
||||
System.out.println("\n" +
|
||||
"___ _ _ ___\n" +
|
||||
" | __| __ _ ___ | || | ___ | __| ___\n" +
|
||||
" | _| / _` | (_-< \\_, | |___| | _| (_-<\n" +
|
||||
" |___| \\__,_| /__/_ _|__/ _____ |___| /__/_\n" +
|
||||
"_|\"\"\"\"\"|_|\"\"\"\"\"|_|\"\"\"\"\"|_| \"\"\"\"|_| |_|\"\"\"\"\"|_|\"\"\"\"\"|\n" +
|
||||
"\"`-0-0-'\"`-0-0-'\"`-0-0-'\"`-0-0-'\"`-0-0-'\"`-0-0-'\"`-0-0-'\n" +
|
||||
"----------------------------------------------------------->"
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// 版本长度并不固定,比如beta版,所以需要特殊处理
|
||||
int width = 38;
|
||||
int width = 43;
|
||||
int blank = width - versionStr.length();
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(":: version :: ")
|
||||
@ -67,11 +97,15 @@ public class MapperScannerRegister implements ImportBeanDefinitionRegistrar, Res
|
||||
sb.append(" ");
|
||||
}
|
||||
sb.append(">");
|
||||
if (iKunMode) {
|
||||
System.out.println("----------------------------------------------------------->");
|
||||
}
|
||||
System.out.println(":: project :: Easy-Es >");
|
||||
System.out.println(sb);
|
||||
System.out.println(":: home :: https://easy-es.cn/ >");
|
||||
System.out.println(":: community :: https://dromara.org/ >");
|
||||
System.out.println(":: wechat :: 252645816, add and become muscle man! >");
|
||||
System.out.println("------------------------------------------------------>");
|
||||
System.out.println(":: home :: https://easy-es.cn/ >");
|
||||
System.out.println(":: community :: https://dromara.org/ >");
|
||||
System.out.println(wechatStr);
|
||||
System.out.println("----------------------------------------------------------->");
|
||||
}
|
||||
|
||||
AnnotationAttributes mapperScanAttrs = AnnotationAttributes
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>org.dromara.easy-es</groupId>
|
||||
<artifactId>easy-es-parent</artifactId>
|
||||
<version>2.0.0-beta4</version>
|
||||
<version>2.0.0-beta5</version>
|
||||
<relativePath>../easy-es-parent</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@ -14,6 +14,10 @@ public interface BaseEsConstants {
|
||||
* 是否打印本框架Banner
|
||||
*/
|
||||
String ENABLE_BANNER = "easy-es.banner";
|
||||
/**
|
||||
* 是否开启iKun模式
|
||||
*/
|
||||
String ENABLE_I_KUN_MODE = "easy-es.global-config.i-kun-mode";
|
||||
/**
|
||||
* 默认主键名称
|
||||
*/
|
||||
@ -139,6 +143,10 @@ public interface BaseEsConstants {
|
||||
* DSL语句前缀
|
||||
*/
|
||||
String DSL_PREFIX = "===> Execute By Easy-Es: ";
|
||||
/**
|
||||
* DSL语句
|
||||
*/
|
||||
String I_KUN_PREFIX = "===> 鸡你太美提醒您, 以下内容由Easy-Es执行:";
|
||||
/**
|
||||
* count DSL语句前缀
|
||||
*/
|
||||
@ -249,4 +257,12 @@ public interface BaseEsConstants {
|
||||
* 缩放因子索引字段名称
|
||||
*/
|
||||
String SCALING_FACTOR_FIELD = "scaling_factor";
|
||||
/**
|
||||
* path分隔符
|
||||
*/
|
||||
String SIGN = "\\.";
|
||||
/**
|
||||
* path分隔符 不转义
|
||||
*/
|
||||
String STR_SIGN = ".";
|
||||
}
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.dromara.easy-es</groupId>
|
||||
<artifactId>easy-es-parent</artifactId>
|
||||
<version>2.0.0-beta4</version>
|
||||
<version>2.0.0-beta5</version>
|
||||
<relativePath>../easy-es-parent</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@ -1,14 +1,14 @@
|
||||
package org.dromara.easyes.core.biz;
|
||||
|
||||
import org.dromara.easyes.annotation.rely.IdType;
|
||||
import org.dromara.easyes.annotation.rely.JoinField;
|
||||
import org.dromara.easyes.annotation.rely.RefreshPolicy;
|
||||
import org.dromara.easyes.common.constants.BaseEsConstants;
|
||||
import com.alibaba.fastjson.PropertyNamingStrategy;
|
||||
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.IdType;
|
||||
import org.dromara.easyes.annotation.rely.JoinField;
|
||||
import org.dromara.easyes.annotation.rely.RefreshPolicy;
|
||||
import org.dromara.easyes.common.constants.BaseEsConstants;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.*;
|
||||
@ -124,7 +124,11 @@ public class EntityInfo {
|
||||
/**
|
||||
* 当前主类的高亮字段列表
|
||||
*/
|
||||
private List<HighLightParam> highLightParams = new ArrayList<>();
|
||||
private List<HighLightParam> highlightParams = new ArrayList<>();
|
||||
/**
|
||||
* 嵌套类-高亮字段列表
|
||||
*/
|
||||
private Map<Class<?>, List<HighLightParam>> nestedHighLightParamsMap = new HashMap<>();
|
||||
/**
|
||||
* fastjson 字段命名策略
|
||||
*/
|
||||
@ -137,6 +141,10 @@ public class EntityInfo {
|
||||
* 实体字段->高亮返回结果 键值对
|
||||
*/
|
||||
private final Map<String, String> highlightFieldMap = new HashMap<>();
|
||||
/**
|
||||
* 嵌套类 实体字段->高亮返回结果字段
|
||||
*/
|
||||
private final Map<Class<?>, Map<String, String>> nestedHighlightFieldMap = new HashMap<>();
|
||||
/**
|
||||
* 实体字段名->es字段类型
|
||||
*/
|
||||
@ -182,6 +190,7 @@ public class EntityInfo {
|
||||
* 数据刷新策略
|
||||
*/
|
||||
private RefreshPolicy refreshPolicy;
|
||||
|
||||
/**
|
||||
* 获取需要进行查询的字段列表
|
||||
*
|
||||
|
||||
@ -21,6 +21,10 @@ public class GlobalConfig {
|
||||
* whether to print dsl log 是否打印执行的dsl语句
|
||||
*/
|
||||
private boolean printDsl = true;
|
||||
/**
|
||||
* for fun, whether to print love chinese "kung fu" mode 是否开启爱坤(小黑子)模式 开启后日志将进入疯狂状态, 后期也会在此特殊模式下提供更多趣味化及傻瓜功能 让编码不仅简单,还有趣!
|
||||
*/
|
||||
private boolean iKunMode;
|
||||
/**
|
||||
* process index mode Manual by default 索引处理模式 默认开启手动模式
|
||||
*/
|
||||
|
||||
@ -18,6 +18,7 @@ import org.dromara.easyes.common.utils.*;
|
||||
import org.dromara.easyes.core.biz.*;
|
||||
import org.dromara.easyes.core.cache.BaseCache;
|
||||
import org.dromara.easyes.core.cache.GlobalConfigCache;
|
||||
import org.dromara.easyes.core.config.GlobalConfig;
|
||||
import org.dromara.easyes.core.toolkit.EntityInfoHelper;
|
||||
import org.dromara.easyes.core.toolkit.FieldUtils;
|
||||
import org.dromara.easyes.core.toolkit.IndexUtils;
|
||||
@ -1053,8 +1054,8 @@ public class BaseEsMapperImpl<T> implements BaseEsMapper<T> {
|
||||
// 解析json
|
||||
T entity = JSON.parseObject(searchHit.getSourceAsString(), entityClass, entityInfo.getExtraProcessor());
|
||||
|
||||
// 高亮字段处理
|
||||
if (CollectionUtils.isNotEmpty(entityInfo.getHighLightParams())) {
|
||||
// 主类中高亮字段处理
|
||||
if (CollectionUtils.isNotEmpty(entityInfo.getHighlightParams())) {
|
||||
Map<String, String> highlightFieldMap = getHighlightFieldMap();
|
||||
Map<String, HighlightField> highlightFields = searchHit.getHighlightFields();
|
||||
highlightFields.forEach((key, value) -> {
|
||||
@ -1063,6 +1064,9 @@ public class BaseEsMapperImpl<T> implements BaseEsMapper<T> {
|
||||
});
|
||||
}
|
||||
|
||||
// 嵌套类中的高亮处理
|
||||
setInnerHighlight(searchHit, entity, entityInfo.getNestedHighlightFieldMap());
|
||||
|
||||
// 得分字段处理
|
||||
setScore(entity, searchHit.getScore(), entityInfo);
|
||||
|
||||
@ -1078,6 +1082,97 @@ public class BaseEsMapperImpl<T> implements BaseEsMapper<T> {
|
||||
return entity;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 设置嵌套类型中的高亮
|
||||
*
|
||||
* @param searchHit 查询结果
|
||||
* @param root 主实体对象
|
||||
* @param nestedHighlightFieldMap 字段缓存
|
||||
*/
|
||||
private void setInnerHighlight(SearchHit searchHit, T root, Map<Class<?>, Map<String, String>> nestedHighlightFieldMap) {
|
||||
// 遍历innerHits 批量设置
|
||||
if (CollectionUtils.isEmpty(searchHit.getInnerHits())) {
|
||||
return;
|
||||
}
|
||||
searchHit.getInnerHits()
|
||||
.forEach((k, v) -> {
|
||||
SearchHit[] hits = v.getHits();
|
||||
Arrays.stream(hits).forEach(hit -> {
|
||||
SearchHit.NestedIdentity nestedIdentity = hit.getNestedIdentity();
|
||||
Map<String, HighlightField> highlightFields = hit.getHighlightFields();
|
||||
if (CollectionUtils.isNotEmpty(highlightFields) && nestedIdentity != null) {
|
||||
highlightFields.forEach((k1, v1) -> {
|
||||
String highLightContent = Arrays.stream(v1.getFragments()).map(Text::string).collect(Collectors.joining());
|
||||
String[] split = k1.split(SIGN);
|
||||
String highLightField = split[split.length - 1];
|
||||
processInnerHighlight(nestedIdentity.getField().string(), root, nestedIdentity,
|
||||
highLightField, highLightContent, nestedHighlightFieldMap);
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 递归处理嵌套类中的高亮
|
||||
*
|
||||
* @param path 嵌套类路径
|
||||
* @param root
|
||||
* @param nestedIdentity 嵌套路径
|
||||
* @param highlightField 高亮字段
|
||||
* @param highlightContent 高亮内容
|
||||
* @param nestedHighlightFieldMap 字段缓存
|
||||
*/
|
||||
private void processInnerHighlight(String path, Object root, SearchHit.NestedIdentity nestedIdentity, String highlightField,
|
||||
String highlightContent, Map<Class<?>, Map<String, String>> nestedHighlightFieldMap) {
|
||||
// 反射, 获取嵌套对象
|
||||
Method method = BaseCache.getterMethod(root.getClass(), nestedIdentity.getField().string());
|
||||
Object invoke = null;
|
||||
try {
|
||||
invoke = method.invoke(root);
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
LogUtils.error("processInnerHighlight invoke error, class:%s,methodName:%s",
|
||||
root.getClass().getSimpleName(), nestedIdentity.getField().string());
|
||||
}
|
||||
|
||||
// 嵌套对象为容器的情况
|
||||
if (invoke instanceof Collection) {
|
||||
Collection<?> coll = (Collection<?>) invoke;
|
||||
Iterator<?> iterator = coll.iterator();
|
||||
int i = 0;
|
||||
while (iterator.hasNext()) {
|
||||
Object next = iterator.next();
|
||||
// 不在nestedIdentity中的项无需处理
|
||||
if (i == nestedIdentity.getOffset()) {
|
||||
if (path.equals(nestedIdentity.getField().string())) {
|
||||
final SearchHit.NestedIdentity child = nestedIdentity.getChild();
|
||||
if (child != null) {
|
||||
// 递归 对子项执行相同操作
|
||||
processInnerHighlight(child.getField().string(), next, child, highlightField, highlightContent, nestedHighlightFieldMap);
|
||||
} else {
|
||||
// 已找到需要被高亮的叶子节点
|
||||
String realHighlightField = Optional.ofNullable(nestedHighlightFieldMap.get(next.getClass()))
|
||||
.map(highlightFieldMap -> highlightFieldMap.get(highlightField)).orElse(highlightField);
|
||||
setHighlightValue(next, realHighlightField, highlightContent);
|
||||
}
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
} else {
|
||||
// 不太可能发生, 因为非容器的嵌套类型无意义,可以直接大宽表,但考虑到健壮性,仍针对个别傻狍子用户兼容处理
|
||||
Object finalInvoke = invoke;
|
||||
Optional.ofNullable(finalInvoke).ifPresent(i -> {
|
||||
String realHighlightField = Optional.ofNullable(nestedHighlightFieldMap.get(finalInvoke.getClass()))
|
||||
.map(highlightFieldMap -> highlightFieldMap.get(highlightField)).orElse(highlightField);
|
||||
setHighlightValue(i, realHighlightField, highlightContent);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 设置距离
|
||||
*
|
||||
@ -1395,9 +1490,9 @@ public class BaseEsMapperImpl<T> implements BaseEsMapper<T> {
|
||||
* @param highlightField 高亮返回字段
|
||||
* @param value 高亮结果值
|
||||
*/
|
||||
private void setHighlightValue(T entity, String highlightField, String value) {
|
||||
private void setHighlightValue(Object entity, String highlightField, String value) {
|
||||
try {
|
||||
Method invokeMethod = BaseCache.setterMethod(entityClass, highlightField);
|
||||
Method invokeMethod = BaseCache.setterMethod(entity.getClass(), highlightField);
|
||||
invokeMethod.invoke(entity, value);
|
||||
} catch (Throwable e) {
|
||||
LogUtils.formatError("setHighlightValue error,entity:%s,highlightField:%s,value:%s,e:%s",
|
||||
@ -1450,12 +1545,18 @@ public class BaseEsMapperImpl<T> implements BaseEsMapper<T> {
|
||||
* @param countRequest 统计数量查询参数
|
||||
*/
|
||||
private void printCountDSL(CountRequest countRequest) {
|
||||
if (GlobalConfigCache.getGlobalConfig().isPrintDsl() && Objects.nonNull(countRequest)) {
|
||||
Optional.ofNullable(countRequest.query())
|
||||
.ifPresent(source -> LogUtils.info(BaseEsConstants.COUNT_DSL_PREFIX
|
||||
+ "\nindex-name: " + org.springframework.util.StringUtils.arrayToCommaDelimitedString(countRequest.indices())
|
||||
+ "\nDSL:" + source));
|
||||
}
|
||||
// GlobalConfig globalConfig = GlobalConfigCache.getGlobalConfig();
|
||||
// if (.isPrintDsl() && Objects.nonNull(countRequest)){
|
||||
// Optional.ofNullable(countRequest.query())
|
||||
// .ifPresent(source -> {
|
||||
// String prefix = globalConfig.isIKunMode() ? I_KUN_PREFIX : DSL_PREFIX;
|
||||
// LogUtils.info(BaseEsConstants.COUNT_DSL_PREFIX
|
||||
// + "\nindex-name: " + org.springframework.util.StringUtils.arrayToCommaDelimitedString(countRequest.indices())
|
||||
// + "\nDSL:" + source)
|
||||
// });
|
||||
// }
|
||||
Optional.ofNullable(countRequest.query())
|
||||
.ifPresent(i -> doPrint(i.toString(), countRequest.indices()));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1464,11 +1565,15 @@ public class BaseEsMapperImpl<T> implements BaseEsMapper<T> {
|
||||
* @param searchRequest es查询请求参数
|
||||
*/
|
||||
private void printDSL(SearchRequest searchRequest) {
|
||||
if (GlobalConfigCache.getGlobalConfig().isPrintDsl() && Objects.nonNull(searchRequest)) {
|
||||
Optional.ofNullable(searchRequest.source())
|
||||
.ifPresent(source -> LogUtils.info(BaseEsConstants.DSL_PREFIX
|
||||
+ "\nindex-name: " + org.springframework.util.StringUtils.arrayToCommaDelimitedString(searchRequest.indices())
|
||||
+ "\nDSL:" + source));
|
||||
Optional.ofNullable(searchRequest.source())
|
||||
.ifPresent(i -> doPrint(i.toString(), searchRequest.indices()));
|
||||
}
|
||||
|
||||
private void doPrint(String source, String[] indices) {
|
||||
GlobalConfig globalConfig = GlobalConfigCache.getGlobalConfig();
|
||||
if (globalConfig.isPrintDsl()) {
|
||||
String prefix = globalConfig.isIKunMode() ? I_KUN_PREFIX : DSL_PREFIX;
|
||||
LogUtils.info(prefix + "\nindex-name: " + String.join(",", indices) + "\nDSL:" + source);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1497,7 +1602,7 @@ public class BaseEsMapperImpl<T> implements BaseEsMapper<T> {
|
||||
private String getRefreshPolicy() {
|
||||
// 防止傻狍子用户在全局中把刷新策略修改为GLOBAL
|
||||
final RefreshPolicy refreshPolicy = EntityInfoHelper.getEntityInfo(entityClass).getRefreshPolicy();
|
||||
return refreshPolicy.equals(RefreshPolicy.GLOBAL) ? RefreshPolicy.NONE.getValue() : refreshPolicy.getValue();
|
||||
return RefreshPolicy.GLOBAL.equals(refreshPolicy) ? RefreshPolicy.NONE.getValue() : refreshPolicy.getValue();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -246,10 +246,14 @@ public class WrapperProcessor {
|
||||
break;
|
||||
case NESTED:
|
||||
realField = getRealField(param.getColumn(), mappingColumnMap);
|
||||
String[] split = param.getColumn().split("\\.");
|
||||
queryBuilder = getBool(children, QueryBuilders.boolQuery(), entityInfo, split[split.length - 1]);
|
||||
queryBuilder = QueryBuilders.nestedQuery(realField, queryBuilder, (ScoreMode) param.getVal());
|
||||
setBool(bool, queryBuilder, param.getPrevQueryType());
|
||||
String[] split = param.getColumn().split(SIGN);
|
||||
String path = split[split.length - 1];
|
||||
queryBuilder = getBool(children, QueryBuilders.boolQuery(), entityInfo, path);
|
||||
NestedQueryBuilder nestedQueryBuilder = QueryBuilders.nestedQuery(realField, queryBuilder, (ScoreMode) param.getVal());
|
||||
// 设置嵌套类型高亮查询参数
|
||||
setNestedHighlight(path, param.getColumn(), nestedQueryBuilder, entityInfo);
|
||||
// 设置bool查询参数
|
||||
setBool(bool, nestedQueryBuilder, param.getPrevQueryType());
|
||||
break;
|
||||
default:
|
||||
// just ignore,almost never happen
|
||||
@ -257,6 +261,27 @@ public class WrapperProcessor {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置嵌套类型高亮查询参数
|
||||
*
|
||||
* @param path 嵌套path
|
||||
* @param column 字段
|
||||
* @param nestedQueryBuilder 嵌套查询条件构造器
|
||||
* @param entityInfo 实体信息缓存
|
||||
*/
|
||||
private static void setNestedHighlight(String path, String column, NestedQueryBuilder nestedQueryBuilder, EntityInfo entityInfo) {
|
||||
// 嵌套类型的高亮查询语句构造
|
||||
Class<?> pathClass = entityInfo.getPathClassMap().get(path);
|
||||
Optional.ofNullable(pathClass)
|
||||
.flatMap(i -> Optional.ofNullable(entityInfo.getNestedHighLightParamsMap().get(i)))
|
||||
.ifPresent(i -> {
|
||||
// 嵌套类型高亮字段名需要完整的path 例如users.faqs 所以此处用param.column而非path
|
||||
HighlightBuilder highlightBuilder = initHighlightBuilder(i, column);
|
||||
Optional.ofNullable(highlightBuilder)
|
||||
.ifPresent(p -> nestedQueryBuilder.innerHit(new InnerHitBuilder().setHighlightBuilder(p)));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置节点的bool
|
||||
*
|
||||
@ -282,8 +307,10 @@ public class WrapperProcessor {
|
||||
/**
|
||||
* 递归获取子节点的bool
|
||||
*
|
||||
* @param paramList 子节点参数列表
|
||||
* @param builder 新的根bool
|
||||
* @param paramList 子节点参数列表
|
||||
* @param builder 新的根bool
|
||||
* @param entityInfo 实体信息缓存
|
||||
* @param path 路径
|
||||
* @return 子节点bool合集, 统一封装至入参builder中
|
||||
*/
|
||||
private static BoolQueryBuilder getBool(List<Param> paramList, BoolQueryBuilder builder, EntityInfo entityInfo, String path) {
|
||||
@ -326,7 +353,7 @@ public class WrapperProcessor {
|
||||
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
|
||||
|
||||
// 设置高亮
|
||||
setHighLight(entityInfo.getHighLightParams(), searchSourceBuilder);
|
||||
setHighLight(entityInfo.getHighlightParams(), searchSourceBuilder);
|
||||
|
||||
// 设置用户指定的各种排序规则
|
||||
setSort(wrapper, mappingColumnMap, searchSourceBuilder);
|
||||
@ -404,12 +431,23 @@ public class WrapperProcessor {
|
||||
return;
|
||||
}
|
||||
|
||||
// 初始化高亮参数
|
||||
HighlightBuilder highlightBuilder = initHighlightBuilder(highLightParams, null);
|
||||
Optional.ofNullable(highlightBuilder).ifPresent(searchSourceBuilder::highlighter);
|
||||
}
|
||||
|
||||
private static HighlightBuilder initHighlightBuilder(List<HighLightParam> highLightParams, String path) {
|
||||
if (CollectionUtils.isEmpty(highLightParams)) {
|
||||
return null;
|
||||
}
|
||||
// 封装高亮参数
|
||||
HighlightBuilder highlightBuilder = new HighlightBuilder();
|
||||
highLightParams.forEach(highLightParam -> {
|
||||
if (StringUtils.isNotBlank(highLightParam.getHighLightField())) {
|
||||
//field
|
||||
HighlightBuilder.Field field = new HighlightBuilder.Field(highLightParam.getHighLightField());
|
||||
// 嵌套类型 须追加其完整path前缀
|
||||
String highlightField = Optional.ofNullable(path).map(i -> i + STR_SIGN + highLightParam.getHighLightField())
|
||||
.orElse(highLightParam.getHighLightField());
|
||||
HighlightBuilder.Field field = new HighlightBuilder.Field(highlightField);
|
||||
field.highlighterType(highLightParam.getHighLightType().getValue());
|
||||
highlightBuilder.field(field);
|
||||
|
||||
@ -419,7 +457,7 @@ public class WrapperProcessor {
|
||||
Optional.ofNullable(highLightParam.getNumberOfFragments()).ifPresent(highlightBuilder::numOfFragments);
|
||||
}
|
||||
});
|
||||
searchSourceBuilder.highlighter(highlightBuilder);
|
||||
return highlightBuilder;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -257,7 +257,7 @@ public class EntityInfoHelper {
|
||||
|
||||
// 初始化封装HighLight注解信息
|
||||
if (field.isAnnotationPresent(HighLight.class)) {
|
||||
initHighLightAnnotation(dbConfig, entityInfo, field);
|
||||
initHighLightAnnotation(dbConfig, entityInfo, field, entityInfo.getMappingColumnMap(), null);
|
||||
// 此处无需返回true阻断流程,可防止用户未添加IndexField时,框架索引跳过读取此字段的信息
|
||||
}
|
||||
|
||||
@ -373,38 +373,71 @@ public class EntityInfoHelper {
|
||||
/**
|
||||
* HighLight注解初始化
|
||||
*
|
||||
* @param dbConfig 索引配置
|
||||
* @param entityInfo 实体信息
|
||||
* @param field 字段
|
||||
* @param dbConfig 索引配置
|
||||
* @param entityInfo 实体信息
|
||||
* @param field 字段
|
||||
* @param mappingColumnMap 实体字段与es字段映射关系
|
||||
* @param nestedClass 嵌套类
|
||||
*/
|
||||
private static void initHighLightAnnotation(GlobalConfig.DbConfig dbConfig, EntityInfo entityInfo, Field field) {
|
||||
private static void initHighLightAnnotation(GlobalConfig.DbConfig dbConfig, EntityInfo entityInfo, Field field,
|
||||
Map<String, String> mappingColumnMap, Class<?> nestedClass) {
|
||||
HighLight highLight = field.getAnnotation(HighLight.class);
|
||||
String mappingField = highLight.mappingField();
|
||||
if (StringUtils.isNotBlank(mappingField)) {
|
||||
entityInfo.getNotSerializeField().add(mappingField);
|
||||
} else {
|
||||
|
||||
// 置入字段json序列化忽略缓存
|
||||
boolean skip = false;
|
||||
if (StringUtils.isBlank(mappingField)) {
|
||||
// 如果用户未指定高亮映射字段,则高亮映射字段用当前字段
|
||||
mappingField = field.getName();
|
||||
// 当使用当前字段作为高亮字段时,当前字段参与索引创建
|
||||
skip = true;
|
||||
}
|
||||
if (!skip) {
|
||||
// 添加无需序列化字段至缓存
|
||||
if (nestedClass == null) {
|
||||
entityInfo.getNotSerializeField().add(mappingField);
|
||||
} else {
|
||||
// 嵌套类型
|
||||
Set<String> nestedNotSerializeFieldSet = Optional.ofNullable(entityInfo.getNestedNotSerializeField().get(nestedClass))
|
||||
.orElse(new HashSet<>());
|
||||
nestedNotSerializeFieldSet.add(mappingField);
|
||||
entityInfo.getNestedNotSerializeField().put(nestedClass, nestedNotSerializeFieldSet);
|
||||
}
|
||||
}
|
||||
|
||||
String customField = entityInfo.getMappingColumnMap().get(field.getName());
|
||||
// 置入高亮字段与实体类中字段名对应关系缓存
|
||||
String customField = mappingColumnMap.get(field.getName());
|
||||
String realHighLightField = Objects.isNull(customField) ? field.getName() : customField;
|
||||
if (dbConfig.isMapUnderscoreToCamelCase()) {
|
||||
realHighLightField = StringUtils.camelToUnderline(realHighLightField);
|
||||
}
|
||||
entityInfo.getHighlightFieldMap().putIfAbsent(realHighLightField, mappingField);
|
||||
if (nestedClass == null) {
|
||||
entityInfo.getHighlightFieldMap().putIfAbsent(realHighLightField, mappingField);
|
||||
} else {
|
||||
Map<String, String> nestedHighlightFieldMap = Optional.ofNullable(entityInfo.getNestedHighlightFieldMap().get(nestedClass))
|
||||
.orElse(new HashMap<>());
|
||||
nestedHighlightFieldMap.putIfAbsent(realHighLightField, mappingField);
|
||||
entityInfo.getNestedHighlightFieldMap().put(nestedClass, nestedHighlightFieldMap);
|
||||
}
|
||||
|
||||
// 封装高亮参数
|
||||
HighLightParam highLightParam = new HighLightParam();
|
||||
highLightParam.setFragmentSize(highLight.fragmentSize())
|
||||
// 置入高亮查询参数缓存
|
||||
HighLightParam highlightParam = new HighLightParam();
|
||||
highlightParam.setFragmentSize(highLight.fragmentSize())
|
||||
.setPreTag(highLight.preTag())
|
||||
.setPostTag(highLight.postTag())
|
||||
.setHighLightField(realHighLightField)
|
||||
.setHighLightType(highLight.highLightType());
|
||||
if (MINUS_ONE != highLight.numberOfFragments() && highLight.numberOfFragments() > ZERO) {
|
||||
highLightParam.setNumberOfFragments(highLight.numberOfFragments());
|
||||
highlightParam.setNumberOfFragments(highLight.numberOfFragments());
|
||||
}
|
||||
if (nestedClass == null) {
|
||||
entityInfo.getHighlightParams().add(highlightParam);
|
||||
} else {
|
||||
List<HighLightParam> nestedHighlightParams = Optional.ofNullable(entityInfo.getNestedHighLightParamsMap().get(nestedClass))
|
||||
.orElse(new ArrayList<>());
|
||||
nestedHighlightParams.add(highlightParam);
|
||||
entityInfo.getNestedHighLightParamsMap().put(nestedClass, nestedHighlightParams);
|
||||
}
|
||||
entityInfo.getHighLightParams().add(highLightParam);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -490,6 +523,10 @@ public class EntityInfoHelper {
|
||||
mappingColumnMap.putIfAbsent(field.getName(), mappingColumn);
|
||||
fieldTypeMap.putIfAbsent(field.getName(), fieldType.getType());
|
||||
|
||||
// 初始化封装嵌套类中的HighLight注解信息
|
||||
if (field.isAnnotationPresent(HighLight.class)) {
|
||||
initHighLightAnnotation(dbConfig, entityInfo, field, mappingColumnMap, nestedClass);
|
||||
}
|
||||
});
|
||||
entityInfo.getNestedNotSerializeField().putIfAbsent(nestedClass, notSerializedFields);
|
||||
entityInfo.getNestedClassColumnMappingMap().putIfAbsent(nestedClass, columnMappingMap);
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.dromara.easy-es</groupId>
|
||||
<artifactId>easy-es-parent</artifactId>
|
||||
<version>2.0.0-beta4</version>
|
||||
<version>2.0.0-beta5</version>
|
||||
<relativePath>../easy-es-parent</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
|
||||
<groupId>org.dromara.easy-es</groupId>
|
||||
<artifactId>easy-es-parent</artifactId>
|
||||
<version>2.0.0-beta4</version>
|
||||
<version>2.0.0-beta5</version>
|
||||
|
||||
<name>easy-es-parent</name>
|
||||
<description>easy use for elastic search</description>
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
<parent>
|
||||
<groupId>org.dromara.easy-es</groupId>
|
||||
<artifactId>easy-es</artifactId>
|
||||
<version>2.0.0-beta4</version>
|
||||
<version>2.0.0-beta5</version>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
package org.dromara.easyes.sample.entity;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
import org.dromara.easyes.annotation.HighLight;
|
||||
import org.dromara.easyes.annotation.IndexField;
|
||||
import org.dromara.easyes.annotation.IndexId;
|
||||
@ -8,8 +10,6 @@ import org.dromara.easyes.annotation.rely.Analyzer;
|
||||
import org.dromara.easyes.annotation.rely.FieldStrategy;
|
||||
import org.dromara.easyes.annotation.rely.FieldType;
|
||||
import org.dromara.easyes.annotation.rely.IdType;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* es 数据模型
|
||||
@ -18,7 +18,7 @@ import lombok.experimental.Accessors;
|
||||
**/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
@IndexName(value = "easyes_document", shardsNum = 3, replicasNum = 2, keepGlobalPrefix = true,maxResultWindow = 100)
|
||||
@IndexName(value = "easyes_document", shardsNum = 3, replicasNum = 2, keepGlobalPrefix = true, maxResultWindow = 100)
|
||||
public class Document {
|
||||
/**
|
||||
* es中的唯一id,如果你想自定义es中的id为你提供的id,比如MySQL中的id,请将注解中的type指定为customize或直接在全局配置文件中指定,如此id便支持任意数据类型)
|
||||
@ -63,7 +63,7 @@ public class Document {
|
||||
/**
|
||||
* 自定义字段名称
|
||||
*/
|
||||
@IndexField(value = "wu-la", fieldType = FieldType.TEXT, analyzer = Analyzer.IK_SMART, searchAnalyzer = Analyzer.IK_SMART,fieldData = true)
|
||||
@IndexField(value = "wu-la", fieldType = FieldType.TEXT, analyzer = Analyzer.IK_SMART, searchAnalyzer = Analyzer.IK_SMART, fieldData = true)
|
||||
private String customField;
|
||||
|
||||
/**
|
||||
|
||||
@ -6,12 +6,13 @@ easy-es:
|
||||
password: WG7WVmuNMtM4GwNYkyWH
|
||||
keep-alive-millis: 18000
|
||||
global-config:
|
||||
i-kun-mode: true
|
||||
process-index-mode: smoothly
|
||||
async-process-index-blocking: true
|
||||
print-dsl: false
|
||||
db-config:
|
||||
map-underscore-to-camel-case: true
|
||||
table-prefix: dev_
|
||||
index-prefix: dev_
|
||||
id-type: customize
|
||||
field-strategy: not_empty
|
||||
refresh-policy: immediate
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.dromara.easy-es</groupId>
|
||||
<artifactId>easy-es</artifactId>
|
||||
<version>2.0.0-beta4</version>
|
||||
<version>2.0.0-beta5</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>easy-es-test</artifactId>
|
||||
|
||||
@ -4,10 +4,11 @@ package org.dromara.easyes.test.entity;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.dromara.easyes.annotation.HighLight;
|
||||
import org.dromara.easyes.annotation.IndexField;
|
||||
|
||||
/**
|
||||
* 文件描述
|
||||
* 问答
|
||||
*
|
||||
* @ProductName: Hundsun HEP
|
||||
* @ProjectName: easy-es
|
||||
@ -26,7 +27,14 @@ import org.dromara.easyes.annotation.IndexField;
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class Faq {
|
||||
/**
|
||||
* 问题 高亮内容直接覆盖在原字段值上进行返回,故不需要指定高亮注解中的mappingField
|
||||
*/
|
||||
@HighLight
|
||||
private String faqName;
|
||||
@IndexField(value = "answer")
|
||||
/**
|
||||
* 答案
|
||||
*/
|
||||
private String faqAnswer;
|
||||
}
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
package org.dromara.easyes.test.entity;
|
||||
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.dromara.easyes.annotation.HighLight;
|
||||
import org.dromara.easyes.annotation.IndexField;
|
||||
import org.dromara.easyes.annotation.rely.Analyzer;
|
||||
import org.dromara.easyes.annotation.rely.FieldType;
|
||||
@ -17,13 +17,21 @@ import java.util.Set;
|
||||
**/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class User {
|
||||
/**
|
||||
* 用户名
|
||||
*/
|
||||
@IndexField(value = "user_name", fieldType = FieldType.TEXT, analyzer = Analyzer.IK_SMART)
|
||||
@HighLight(mappingField = "highlightUsername")
|
||||
private String username;
|
||||
/**
|
||||
* 年龄
|
||||
*/
|
||||
@IndexField(fieldType = FieldType.INTEGER)
|
||||
private Integer age;
|
||||
|
||||
/**
|
||||
* 密码
|
||||
*/
|
||||
@IndexField(fieldType = FieldType.KEYWORD)
|
||||
private String password;
|
||||
/**
|
||||
@ -31,4 +39,15 @@ public class User {
|
||||
*/
|
||||
@IndexField(fieldType = FieldType.NESTED, nestedClass = Faq.class)
|
||||
private Set<Faq> faqs;
|
||||
/**
|
||||
* 高亮显示的内容
|
||||
*/
|
||||
private String highlightUsername;
|
||||
|
||||
public User(String username, Integer age, String password, Set<Faq> faqs) {
|
||||
this.username = username;
|
||||
this.age = age;
|
||||
this.password = password;
|
||||
this.faqs = faqs;
|
||||
}
|
||||
}
|
||||
|
||||
@ -11,6 +11,7 @@ import org.dromara.easyes.test.mapper.DocumentMapper;
|
||||
import org.elasticsearch.geometry.Point;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Order;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
|
||||
@ -34,6 +35,15 @@ public class NestedTest {
|
||||
private DocumentMapper documentMapper;
|
||||
|
||||
@Test
|
||||
@Order(0)
|
||||
public void testCreateIndex() {
|
||||
// 初始化创建索引,配置开启手动挡后执行
|
||||
final Boolean success = documentMapper.createIndex();
|
||||
Assertions.assertTrue(success);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(1)
|
||||
public void testInsert() {
|
||||
// 测试插入数据
|
||||
Document document = new Document();
|
||||
@ -49,14 +59,14 @@ public class NestedTest {
|
||||
document.setStarNum(1);
|
||||
List<User> users = new ArrayList<>();
|
||||
Set<Faq> faqs = new HashSet<>();
|
||||
faqs.add(new Faq("问题1", "回答1"));
|
||||
faqs.add(new Faq("问题2", "回答2"));
|
||||
faqs.add(new Faq("q1", "回答1"));
|
||||
faqs.add(new Faq("q2", "回答2"));
|
||||
|
||||
Set<Faq> faqs1 = new HashSet<>();
|
||||
faqs1.add(new Faq("问题3", "回答3"));
|
||||
faqs1.add(new Faq("问题4", "回答4"));
|
||||
users.add(new User("用户1", 18, "12345", faqs));
|
||||
users.add(new User("用户2", 19, "123", faqs1));
|
||||
faqs1.add(new Faq("q4", "回答3"));
|
||||
faqs1.add(new Faq("q3", "回答4"));
|
||||
users.add(new User("u1", 18, "12345", faqs));
|
||||
users.add(new User("u2", 19, "123", faqs1));
|
||||
document.setUsers(users);
|
||||
int successCount = documentMapper.insert(document);
|
||||
Assertions.assertEquals(successCount, 1);
|
||||
@ -65,19 +75,20 @@ public class NestedTest {
|
||||
users.clear();
|
||||
faqs.clear();
|
||||
faqs1.clear();
|
||||
faqs.add(new Faq("question1", "answer1"));
|
||||
faqs.add(new Faq("question2", "answer2"));
|
||||
faqs.add(new Faq("q1", "answer1"));
|
||||
faqs.add(new Faq("q2", "answer2"));
|
||||
|
||||
faqs1.add(new Faq("q3", "a3"));
|
||||
faqs1.add(new Faq("q4", "a4"));
|
||||
users.add(new User("user1", 8, "12345", faqs));
|
||||
users.add(new User("u2", 9, "54321", faqs1));
|
||||
users.add(new User("u3", 8, "12345", faqs));
|
||||
users.add(new User("u4", 9, "54321", faqs1));
|
||||
document.setUsers(users);
|
||||
successCount = documentMapper.insert(document);
|
||||
Assertions.assertEquals(successCount, 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(2)
|
||||
public void testNestedMatch() {
|
||||
// 嵌套查询 查询年龄等于18或8,且密码等于12345的数据
|
||||
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
|
||||
@ -89,10 +100,10 @@ public class NestedTest {
|
||||
|
||||
// 嵌套类型中的字段获取可以用FieldUtils.val或直接传入字符串
|
||||
LambdaEsQueryWrapper<Document> wrapper1 = new LambdaEsQueryWrapper<>();
|
||||
wrapper1.eq(Document::getTitle,"老汉")
|
||||
wrapper1.eq(Document::getTitle, "老汉")
|
||||
.nested("users.faqs", w -> w.eq("users.faqs.answer", "a4")
|
||||
.match("users.faqs.faq_name", "q4"))
|
||||
.nested("users", w -> w.between("users.age", 1, 30))
|
||||
.nested("users", w -> w.match("users.user_name", "u3"))
|
||||
.match(Document::getCreator, "吃饭");
|
||||
List<Document> documents1 = documentMapper.selectList(wrapper1);
|
||||
System.out.println(documents1);
|
||||
@ -106,7 +117,7 @@ public class NestedTest {
|
||||
System.out.println(documents2);
|
||||
|
||||
LambdaEsQueryWrapper<Document> wrapper3 = new LambdaEsQueryWrapper<>();
|
||||
wrapper3.nested("users.faqs",w->w.match("users.faqs.faq_name", "q3").or().match("users.faqs.faq_name","q4"));
|
||||
wrapper3.nested("users.faqs", w -> w.match("users.faqs.faq_name", "q3").or().match("users.faqs.faq_name", "q4"));
|
||||
List<Document> documents3 = documentMapper.selectList(wrapper3);
|
||||
System.out.println(documents3);
|
||||
}
|
||||
|
||||
@ -13,6 +13,7 @@ import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* searchAfter测试
|
||||
@ -32,9 +33,38 @@ public class SearchAfterTest {
|
||||
//重现bug需要注释掉searchAfter中对from的校验
|
||||
// lambdaEsQueryWrapper.from(10);
|
||||
SAPageInfo<Document> saPageInfo = documentMapper.searchAfterPage(lambdaEsQueryWrapper, null, 10);
|
||||
|
||||
//第一页
|
||||
System.out.println(saPageInfo);
|
||||
Assertions.assertEquals(10, saPageInfo.getList().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test1() {
|
||||
documentMapper.createIndex();
|
||||
for (int i = 0; i < 30; i++) {
|
||||
Document document = new Document();
|
||||
document.setEsId(String.valueOf(i));
|
||||
document.setTitle("测试标题" + i);
|
||||
document.setContent("测试内容" + i);
|
||||
documentMapper.insert(document);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test2() {
|
||||
LambdaEsQueryWrapper<Document> wrapper = EsWrappers.lambdaQuery(Document.class);
|
||||
wrapper.match(Document::getContent, "测试");
|
||||
wrapper.orderByDesc(Document::getEsId);
|
||||
|
||||
// 第一页,可传null,查完把saPageInfo返回给前端
|
||||
SAPageInfo<Document> saPageInfo = documentMapper.searchAfterPage(wrapper, null, 10);
|
||||
System.out.println(saPageInfo);
|
||||
|
||||
// 第二页,从saPageInfo中把上一次的nextSearchAfter回传给后端
|
||||
List<Object> nextSearchAfter = saPageInfo.getNextSearchAfter();
|
||||
SAPageInfo<Document> saPageInfo1 = documentMapper.searchAfterPage(wrapper, nextSearchAfter, 10);
|
||||
System.out.println(saPageInfo1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -6,6 +6,7 @@ easy-es:
|
||||
# password: WG7WVmuNMtM4GwNYkyWH
|
||||
keep-alive-millis: 18000
|
||||
global-config:
|
||||
i-kun-mode: true
|
||||
process-index-mode: manual
|
||||
async-process-index-blocking: true
|
||||
print-dsl: true
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user