mirror of
https://gitee.com/dromara/easy-es.git
synced 2025-12-06 17:18:57 +08:00
and or tree
This commit is contained in:
parent
c1205453fa
commit
e26449a6b5
@ -1,7 +1,5 @@
|
||||
package cn.easyes.common.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import org.elasticsearch.index.query.RangeQueryBuilder;
|
||||
|
||||
import java.time.LocalDate;
|
||||
@ -14,20 +12,19 @@ import java.util.Date;
|
||||
* <p>
|
||||
* Copyright © 2021 xpc1024 All Rights Reserved
|
||||
**/
|
||||
@AllArgsConstructor
|
||||
public enum EsQueryTypeEnum {
|
||||
/**
|
||||
* 精确值匹配 相当于MySQL 等于
|
||||
*/
|
||||
TERM_QUERY(1),
|
||||
TERM_QUERY,
|
||||
/**
|
||||
* 精确值列表匹配 相当于mysql in
|
||||
*/
|
||||
TERMS_QUERY(2),
|
||||
TERMS_QUERY,
|
||||
/**
|
||||
* 模糊匹配 分词 相当于mysql like
|
||||
*/
|
||||
MATCH_QUERY(3),
|
||||
MATCH_QUERY,
|
||||
/**
|
||||
* 范围查询
|
||||
* <p>
|
||||
@ -48,51 +45,66 @@ public enum EsQueryTypeEnum {
|
||||
* <li>3-2: 我们一般应该使用,东八区,Asia/Shanghai</li>
|
||||
* </ul>
|
||||
*/
|
||||
RANGE_QUERY(4),
|
||||
RANGE_GE,
|
||||
RANGE_GT,
|
||||
RANGE_LE,
|
||||
RANGE_LT,
|
||||
/**
|
||||
* 区间查询,特殊的RANGE_QUERY 相当于mysql between
|
||||
*/
|
||||
INTERVAL_QUERY(5),
|
||||
INTERVAL_QUERY,
|
||||
/**
|
||||
* 存在查询 相当于Mysql中的 is null,not null这种查询类型
|
||||
*/
|
||||
EXISTS_QUERY(6),
|
||||
EXISTS_QUERY,
|
||||
/**
|
||||
* 聚合查询 相当于mysql中的 group by 当然 不仅限于group by 还新增了 sum,avg,max,min等功能
|
||||
*/
|
||||
AGGREGATION_QUERY(7),
|
||||
AGGREGATION_QUERY,
|
||||
/**
|
||||
* 通配,相当于mysql中的like
|
||||
*/
|
||||
WILDCARD_QUERY(8),
|
||||
WILDCARD_QUERY,
|
||||
WILDCARD_LEFT_QUERY,
|
||||
WILDCARD_RIGHT_QUERY,
|
||||
/**
|
||||
* 分词匹配 需要结果中也包含所有的分词,且顺序一样
|
||||
*/
|
||||
MATCH_PHRASE(9),
|
||||
MATCH_PHRASE,
|
||||
/**
|
||||
* 查询全部文档 相当于select all
|
||||
*/
|
||||
MATCH_ALL_QUERY(10),
|
||||
MATCH_ALL_QUERY,
|
||||
/**
|
||||
* 前缀匹配
|
||||
*/
|
||||
MATCH_PHRASE_PREFIX(11),
|
||||
MATCH_PHRASE_PREFIX,
|
||||
/**
|
||||
* 多字段匹配
|
||||
*/
|
||||
MULTI_MATCH_QUERY(12),
|
||||
MULTI_MATCH_QUERY,
|
||||
/**
|
||||
* 所有字段中搜索
|
||||
*/
|
||||
QUERY_STRING_QUERY(13),
|
||||
QUERY_STRING_QUERY,
|
||||
/**
|
||||
* 前缀匹配搜索
|
||||
*/
|
||||
PREFIX_QUERY(14);
|
||||
|
||||
PREFIX_QUERY,
|
||||
/**
|
||||
* 类型
|
||||
* 与条件,相当于mysql中的and,必须满足且返回得分
|
||||
*/
|
||||
@Getter
|
||||
private Integer type;
|
||||
AND_MUST,
|
||||
/**
|
||||
* 取反的与条件,必须不满足
|
||||
*/
|
||||
MUST_NOT,
|
||||
/**
|
||||
* 与条件必须满足,但不返回得分,效率更高
|
||||
*/
|
||||
FILTER,
|
||||
/**
|
||||
* 或条件,相当于mysql中的or
|
||||
*/
|
||||
OR_SHOULD;
|
||||
}
|
||||
|
||||
@ -0,0 +1,25 @@
|
||||
package cn.easyes.common.enums;
|
||||
|
||||
/**
|
||||
* 查询参数Nested类型枚举
|
||||
* <p>
|
||||
* Copyright © 2021 xpc1024 All Rights Reserved
|
||||
**/
|
||||
public enum NestedEnum {
|
||||
/**
|
||||
* 与条件,相当于mysql中的and,必须满足且返回得分
|
||||
*/
|
||||
MUST,
|
||||
/**
|
||||
* 取反的与条件,必须不满足
|
||||
*/
|
||||
MUST_NOT,
|
||||
/**
|
||||
* 与条件必须满足,但不返回得分,效率更高
|
||||
*/
|
||||
FILTER,
|
||||
/**
|
||||
* 或条件,相当于mysql中的or
|
||||
*/
|
||||
SHOULD;
|
||||
}
|
||||
30
easy-es-core/src/main/java/cn/easyes/core/Param.java
Normal file
30
easy-es-core/src/main/java/cn/easyes/core/Param.java
Normal file
@ -0,0 +1,30 @@
|
||||
package cn.easyes.core;
|
||||
|
||||
import cn.easyes.common.enums.EsQueryTypeEnum;
|
||||
import cn.easyes.core.toolkit.Tree;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 查询参数树
|
||||
* <p>
|
||||
* Copyright © 2022 xpc1024 All Rights Reserved
|
||||
**/
|
||||
@Data
|
||||
public class Param extends Tree {
|
||||
/**
|
||||
* 节点类型
|
||||
*/
|
||||
private EsQueryTypeEnum queryTypeEnum;
|
||||
/**
|
||||
* 字段名称
|
||||
*/
|
||||
private String column;
|
||||
/**
|
||||
* 字段值
|
||||
*/
|
||||
private Object val;
|
||||
/**
|
||||
* 权重
|
||||
*/
|
||||
private Float boost;
|
||||
}
|
||||
@ -61,13 +61,6 @@ public abstract class AbstractChainWrapper<T, R, Children extends AbstractChainW
|
||||
return typedThis;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Children ne(boolean condition, R column, Object val, Float boost) {
|
||||
getWrapper().ne(condition, column, val, boost);
|
||||
return typedThis;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Children gt(boolean condition, R column, Object val, Float boost) {
|
||||
getWrapper().gt(condition, column, val, boost);
|
||||
@ -152,23 +145,12 @@ public abstract class AbstractChainWrapper<T, R, Children extends AbstractChainW
|
||||
return typedThis;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Children notMatch(boolean condition, R column, Object val, Float boost) {
|
||||
getWrapper().notMatch(condition, column, val, boost);
|
||||
return typedThis;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Children like(boolean condition, R column, Object val, Float boost) {
|
||||
getWrapper().like(condition, column, val, boost);
|
||||
return typedThis;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Children notLike(boolean condition, R column, Object val, Float boost) {
|
||||
getWrapper().notLike(condition, column, val, boost);
|
||||
return typedThis;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Children likeLeft(boolean condition, R column, Object val, Float boost) {
|
||||
@ -277,24 +259,12 @@ public abstract class AbstractChainWrapper<T, R, Children extends AbstractChainW
|
||||
return typedThis;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Children or(boolean condition) {
|
||||
getWrapper().or(condition);
|
||||
return typedThis;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Children match(R column, Object val, Float boost) {
|
||||
getWrapper().match(column, val, boost);
|
||||
return typedThis;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Children notMatch(R column, Object val, Float boost) {
|
||||
getWrapper().notMatch(column, val, boost);
|
||||
return typedThis;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Children gt(R column, Object val, Float boost) {
|
||||
getWrapper().gt(column, val, boost);
|
||||
@ -337,12 +307,6 @@ public abstract class AbstractChainWrapper<T, R, Children extends AbstractChainW
|
||||
return typedThis;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Children notLike(R column, Object val, Float boost) {
|
||||
getWrapper().notLike(column, val, boost);
|
||||
return typedThis;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Children likeLeft(R column, Object val, Float boost) {
|
||||
getWrapper().likeLeft(column, val, boost);
|
||||
@ -445,13 +409,6 @@ public abstract class AbstractChainWrapper<T, R, Children extends AbstractChainW
|
||||
return typedThis;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Children ne(boolean condition, String column, Object val, Float boost) {
|
||||
getWrapper().ne(condition, column, val, boost);
|
||||
return typedThis;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Children match(boolean condition, String column, Object val, Float boost) {
|
||||
getWrapper().match(condition, column, val, boost);
|
||||
@ -482,12 +439,6 @@ public abstract class AbstractChainWrapper<T, R, Children extends AbstractChainW
|
||||
return typedThis;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Children notMatch(boolean condition, String column, Object val, Float boost) {
|
||||
getWrapper().notMatch(condition, column, val, boost);
|
||||
return typedThis;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Children gt(boolean condition, String column, Object val, Float boost) {
|
||||
getWrapper().gt(condition, column, val, boost);
|
||||
@ -532,12 +483,6 @@ public abstract class AbstractChainWrapper<T, R, Children extends AbstractChainW
|
||||
return typedThis;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Children notLike(boolean condition, String column, Object val, Float boost) {
|
||||
getWrapper().notLike(condition, column, val, boost);
|
||||
return typedThis;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Children likeLeft(boolean condition, String column, Object val, Float boost) {
|
||||
getWrapper().likeLeft(condition, column, val, boost);
|
||||
|
||||
@ -2,8 +2,12 @@ package cn.easyes.core.conditions;
|
||||
|
||||
import cn.easyes.common.enums.*;
|
||||
import cn.easyes.common.utils.*;
|
||||
import cn.easyes.core.Param;
|
||||
import cn.easyes.core.biz.*;
|
||||
import cn.easyes.core.conditions.interfaces.*;
|
||||
import cn.easyes.core.conditions.interfaces.Compare;
|
||||
import cn.easyes.core.conditions.interfaces.Func;
|
||||
import cn.easyes.core.conditions.interfaces.Geo;
|
||||
import cn.easyes.core.conditions.interfaces.Nested;
|
||||
import org.apache.lucene.search.join.ScoreMode;
|
||||
import org.elasticsearch.common.geo.GeoDistance;
|
||||
import org.elasticsearch.common.geo.GeoPoint;
|
||||
@ -18,8 +22,8 @@ import java.util.*;
|
||||
import java.util.function.BiPredicate;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import static cn.easyes.common.enums.BaseEsParamTypeEnum.*;
|
||||
import static cn.easyes.common.enums.EsAttachTypeEnum.*;
|
||||
import static cn.easyes.common.enums.EsAttachTypeEnum.MUST;
|
||||
import static cn.easyes.common.enums.EsAttachTypeEnum.MUST_MULTI_FIELDS;
|
||||
import static cn.easyes.common.enums.EsQueryTypeEnum.*;
|
||||
import static cn.easyes.common.enums.JoinTypeEnum.*;
|
||||
import static cn.easyes.common.enums.OrderTypeEnum.CUSTOMIZE;
|
||||
@ -30,10 +34,23 @@ import static cn.easyes.common.enums.OrderTypeEnum.CUSTOMIZE;
|
||||
* Copyright © 2021 xpc1024 All Rights Reserved
|
||||
**/
|
||||
public abstract class AbstractWrapper<T, R, Children extends AbstractWrapper<T, R, Children>> extends Wrapper<T>
|
||||
implements Compare<Children, R>, Nested<Children, Children>, Join<Children>, Func<Children, R>, Geo<Children, R> {
|
||||
implements Compare<Children, R>, Nested<Children, Children>, Func<Children, R>, Geo<Children, R> {
|
||||
|
||||
protected final Children typedThis = (Children) this;
|
||||
|
||||
/**
|
||||
* 存放树的高度
|
||||
*/
|
||||
protected Integer level;
|
||||
/**
|
||||
* 全局父节点 每次指向nested条件后
|
||||
*/
|
||||
protected String parentId;
|
||||
/**
|
||||
*
|
||||
*/
|
||||
protected List<Param> paramList;
|
||||
protected LinkedList<String> queue;
|
||||
/**
|
||||
* 基础查询参数列表
|
||||
*/
|
||||
@ -105,6 +122,9 @@ public abstract class AbstractWrapper<T, R, Children extends AbstractWrapper<T,
|
||||
baseEsParamList = new ArrayList<>();
|
||||
baseSortParams = new ArrayList<>();
|
||||
aggregationParamList = new ArrayList<>();
|
||||
paramList = new ArrayList<>();
|
||||
level = 0;
|
||||
queue = new LinkedList<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -143,27 +163,61 @@ public abstract class AbstractWrapper<T, R, Children extends AbstractWrapper<T,
|
||||
|
||||
@Override
|
||||
public Children eq(boolean condition, String column, Object val, Float boost) {
|
||||
return doIt(condition, TERM_QUERY, MUST, column, val, boost);
|
||||
return addParam(condition, TERM_QUERY, column, val, boost);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Children ne(boolean condition, String column, Object val, Float boost) {
|
||||
return doIt(condition, TERM_QUERY, MUST_NOT, column, val, boost);
|
||||
|
||||
private Children addParam(boolean condition, EsQueryTypeEnum queryTypeEnum, String column, Object val, Float boost) {
|
||||
if (condition) {
|
||||
Param param = new Param();
|
||||
param.setId(UUID.randomUUID().toString());
|
||||
Optional.ofNullable(parentId).ifPresent(param::setParentId);
|
||||
param.setQueryTypeEnum(queryTypeEnum);
|
||||
param.setVal(val);
|
||||
param.setColumn(column);
|
||||
param.setBoost(boost);
|
||||
paramList.add(param);
|
||||
}
|
||||
return typedThis;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Children and(boolean condition, Consumer<Children> consumer) {
|
||||
return doIt(condition, consumer, AND_LEFT_BRACKET, AND_RIGHT_BRACKET);
|
||||
return addNested(condition, AND_MUST, consumer);
|
||||
}
|
||||
|
||||
private Children addNested(boolean condition, EsQueryTypeEnum queryTypeEnum, Consumer<Children> consumer) {
|
||||
if (condition) {
|
||||
Param param = new Param();
|
||||
param.setId(UUID.randomUUID().toString());
|
||||
Optional.ofNullable(parentId).ifPresent(param::setParentId);
|
||||
param.setQueryTypeEnum(queryTypeEnum);
|
||||
level++;
|
||||
paramList.add(param);
|
||||
this.parentId = param.getId();
|
||||
queue.push(parentId);
|
||||
consumer.accept(instance());
|
||||
// 深度优先在consumer条件消费完后会来执行这里 此时parentId需要重置 至于为什么 可断点打在consumer前后观察一波 整个框架最难的地方就在此
|
||||
level--;
|
||||
if (!queue.isEmpty()) {
|
||||
this.parentId = queue.pollLast();
|
||||
}
|
||||
if (level == 0) {
|
||||
// 根节点 没爹了
|
||||
this.parentId = null;
|
||||
}
|
||||
}
|
||||
return typedThis;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Children or(boolean condition, Consumer<Children> consumer) {
|
||||
return doIt(condition, consumer, OR_LEFT_BRACKET, OR_RIGHT_BRACKET);
|
||||
return addNested(condition, OR_SHOULD, consumer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Children match(boolean condition, String column, Object val, Float boost) {
|
||||
return doIt(condition, MATCH_QUERY, MUST, column, val, boost);
|
||||
return addParam(condition, MATCH_QUERY, column, val, boost);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -189,7 +243,7 @@ public abstract class AbstractWrapper<T, R, Children extends AbstractWrapper<T,
|
||||
|
||||
@Override
|
||||
public Children matchPhrase(boolean condition, String column, Object val, Float boost) {
|
||||
return doIt(condition, MATCH_PHRASE, MUST, column, val, boost);
|
||||
return addParam(condition, MATCH_PHRASE, column, val, boost);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -227,32 +281,28 @@ public abstract class AbstractWrapper<T, R, Children extends AbstractWrapper<T,
|
||||
if (StringUtils.isBlank(prefix)) {
|
||||
throw ExceptionUtils.eee("prefix can't be blank");
|
||||
}
|
||||
return doIt(condition, PREFIX_QUERY, MUST, column, prefix, boost);
|
||||
return addParam(condition, PREFIX_QUERY, column, prefix, boost);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Children notMatch(boolean condition, String column, Object val, Float boost) {
|
||||
return doIt(condition, MATCH_QUERY, MUST_NOT, column, val, boost);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Children gt(boolean condition, String column, Object val, Float boost) {
|
||||
return doIt(condition, RANGE_QUERY, EsAttachTypeEnum.GT, column, val, boost);
|
||||
return addParam(condition, RANGE_GT, column, val, boost);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Children ge(boolean condition, String column, Object val, Float boost) {
|
||||
return doIt(condition, RANGE_QUERY, EsAttachTypeEnum.GE, column, val, boost);
|
||||
return addParam(condition, RANGE_GE, column, val, boost);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Children lt(boolean condition, String column, Object val, Float boost) {
|
||||
return doIt(condition, RANGE_QUERY, EsAttachTypeEnum.LT, column, val, boost);
|
||||
return addParam(condition, RANGE_LT, column, val, boost);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Children le(boolean condition, String column, Object val, Float boost) {
|
||||
return doIt(condition, RANGE_QUERY, EsAttachTypeEnum.LE, column, val, boost);
|
||||
return addParam(condition, RANGE_LE, column, val, boost);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -265,34 +315,19 @@ public abstract class AbstractWrapper<T, R, Children extends AbstractWrapper<T,
|
||||
return doIt(condition, EsAttachTypeEnum.NOT_BETWEEN, column, val1, val2, boost);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Children or(boolean condition) {
|
||||
if (condition) {
|
||||
BaseEsParam baseEsParam = new BaseEsParam();
|
||||
baseEsParam.setType(BaseEsParamTypeEnum.OR_ALL.getType());
|
||||
baseEsParamList.add(baseEsParam);
|
||||
}
|
||||
return typedThis;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Children like(boolean condition, String column, Object val, Float boost) {
|
||||
return doIt(condition, WILDCARD_QUERY, MUST, column, val, boost);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Children notLike(boolean condition, String column, Object val, Float boost) {
|
||||
return doIt(condition, WILDCARD_QUERY, MUST_NOT, column, val, boost);
|
||||
return addParam(condition, WILDCARD_QUERY, column, val, boost);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Children likeLeft(boolean condition, String column, Object val, Float boost) {
|
||||
return doIt(condition, WILDCARD_QUERY, LIKE_LEFT, column, val, boost);
|
||||
return addParam(condition, WILDCARD_LEFT_QUERY, column, val, boost);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Children likeRight(boolean condition, String column, Object val, Float boost) {
|
||||
return doIt(condition, WILDCARD_QUERY, LIKE_RIGHT, column, val, boost);
|
||||
return addParam(condition, WILDCARD_RIGHT_QUERY, column, val, boost);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -607,7 +642,7 @@ public abstract class AbstractWrapper<T, R, Children extends AbstractWrapper<T,
|
||||
.field(field)
|
||||
.values(values)
|
||||
.boost(boost)
|
||||
.esQueryType(TERMS_QUERY.getType())
|
||||
// .esQueryType(TERMS_QUERY.getType())
|
||||
.originalAttachType(attachTypeEnum.getType())
|
||||
.build();
|
||||
|
||||
@ -653,7 +688,7 @@ public abstract class AbstractWrapper<T, R, Children extends AbstractWrapper<T,
|
||||
.field(field)
|
||||
.value(val)
|
||||
.boost(boost)
|
||||
.esQueryType(queryTypeEnum.getType())
|
||||
// .esQueryType(queryTypeEnum.getType())
|
||||
.originalAttachType(attachTypeEnum.getType())
|
||||
.ext(ext)
|
||||
.build();
|
||||
@ -681,7 +716,7 @@ public abstract class AbstractWrapper<T, R, Children extends AbstractWrapper<T,
|
||||
.builder()
|
||||
.field(field)
|
||||
.boost(boost)
|
||||
.esQueryType(EXISTS_QUERY.getType())
|
||||
// .esQueryType(EXISTS_QUERY.getType())
|
||||
.originalAttachType(attachTypeEnum.getType())
|
||||
.build();
|
||||
|
||||
@ -712,7 +747,7 @@ public abstract class AbstractWrapper<T, R, Children extends AbstractWrapper<T,
|
||||
.leftValue(left)
|
||||
.rightValue(right)
|
||||
.boost(boost)
|
||||
.esQueryType(INTERVAL_QUERY.getType())
|
||||
// .esQueryType(INTERVAL_QUERY.getType())
|
||||
.originalAttachType(attachTypeEnum.getType())
|
||||
.build();
|
||||
|
||||
@ -746,7 +781,7 @@ public abstract class AbstractWrapper<T, R, Children extends AbstractWrapper<T,
|
||||
.ext(operator)
|
||||
.minimumShouldMatch(minimumShouldMatch)
|
||||
.boost(boost)
|
||||
.esQueryType(queryTypeEnum.getType())
|
||||
// .esQueryType(queryTypeEnum.getType())
|
||||
.originalAttachType(attachTypeEnum.getType())
|
||||
.build();
|
||||
setModel(baseEsParam, model, attachTypeEnum);
|
||||
@ -768,7 +803,7 @@ public abstract class AbstractWrapper<T, R, Children extends AbstractWrapper<T,
|
||||
.value(val)
|
||||
.boost(boost)
|
||||
.ext(joinTypeEnum)
|
||||
.esQueryType(queryTypeEnum.getType())
|
||||
// .esQueryType(queryTypeEnum.getType())
|
||||
.originalAttachType(attachTypeEnum.getType())
|
||||
.build();
|
||||
|
||||
|
||||
@ -3,13 +3,18 @@ package cn.easyes.core.conditions;
|
||||
import cn.easyes.common.params.SFunction;
|
||||
import cn.easyes.common.utils.ArrayUtils;
|
||||
import cn.easyes.common.utils.ExceptionUtils;
|
||||
import cn.easyes.core.biz.*;
|
||||
import cn.easyes.core.Param;
|
||||
import cn.easyes.core.biz.AggregationParam;
|
||||
import cn.easyes.core.biz.BaseSortParam;
|
||||
import cn.easyes.core.biz.EntityFieldInfo;
|
||||
import cn.easyes.core.conditions.interfaces.Query;
|
||||
import cn.easyes.core.toolkit.EntityInfoHelper;
|
||||
import org.elasticsearch.action.search.SearchRequest;
|
||||
import org.elasticsearch.search.builder.SearchSourceBuilder;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
/**
|
||||
@ -61,19 +66,22 @@ public class LambdaEsQueryWrapper<T> extends AbstractLambdaQueryWrapper<T, Lambd
|
||||
exclude = new String[]{};
|
||||
}
|
||||
|
||||
LambdaEsQueryWrapper(T entity, List<BaseEsParam> baseEsParamList, List<BaseSortParam> baseSortParams,
|
||||
LambdaEsQueryWrapper(T entity, List<Param> paramList, LinkedList<String> queue, Integer level, String parentId, List<BaseSortParam> baseSortParams,
|
||||
List<AggregationParam> aggregationParamList) {
|
||||
super.setEntity(entity);
|
||||
include = new String[]{};
|
||||
exclude = new String[]{};
|
||||
this.baseEsParamList = baseEsParamList;
|
||||
this.queue = queue;
|
||||
this.level = level;
|
||||
this.parentId = parentId;
|
||||
this.paramList = paramList;
|
||||
this.baseSortParams = baseSortParams;
|
||||
this.aggregationParamList = aggregationParamList;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected LambdaEsQueryWrapper<T> instance() {
|
||||
return new LambdaEsQueryWrapper<>(entity, baseEsParamList, baseSortParams, aggregationParamList);
|
||||
return new LambdaEsQueryWrapper<>(entity, paramList, queue, level, parentId, baseSortParams, aggregationParamList);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -1,16 +1,15 @@
|
||||
package cn.easyes.core.conditions;
|
||||
|
||||
import cn.easyes.common.enums.AggregationTypeEnum;
|
||||
import cn.easyes.common.utils.ArrayUtils;
|
||||
import cn.easyes.common.utils.CollectionUtils;
|
||||
import cn.easyes.common.utils.MyOptional;
|
||||
import cn.easyes.common.utils.StringUtils;
|
||||
import cn.easyes.common.utils.*;
|
||||
import cn.easyes.core.Param;
|
||||
import cn.easyes.core.biz.*;
|
||||
import cn.easyes.core.cache.GlobalConfigCache;
|
||||
import cn.easyes.core.config.GlobalConfig;
|
||||
import cn.easyes.core.toolkit.EntityInfoHelper;
|
||||
import cn.easyes.core.toolkit.EsQueryTypeUtil;
|
||||
import cn.easyes.core.toolkit.FieldUtils;
|
||||
import cn.easyes.core.toolkit.TreeBuilder;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.SneakyThrows;
|
||||
import org.elasticsearch.index.query.*;
|
||||
@ -26,6 +25,7 @@ import org.elasticsearch.search.sort.SortBuilders;
|
||||
import org.elasticsearch.search.sort.SortOrder;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static cn.easyes.common.constants.BaseEsConstants.DEFAULT_SIZE;
|
||||
import static cn.easyes.common.constants.BaseEsConstants.REPEAT_NUM_KEY;
|
||||
@ -50,7 +50,8 @@ public class WrapperProcessor {
|
||||
*/
|
||||
public static SearchSourceBuilder buildSearchSourceBuilder(LambdaEsQueryWrapper<?> wrapper, Class<?> entityClass) {
|
||||
// 初始化boolQueryBuilder 参数
|
||||
BoolQueryBuilder boolQueryBuilder = initBoolQueryBuilder(wrapper.baseEsParamList, wrapper.enableMust2Filter, entityClass);
|
||||
BoolQueryBuilder boolQueryBuilder = initBoolQueryBuilder(wrapper.paramList, entityClass);
|
||||
System.out.println(boolQueryBuilder);
|
||||
|
||||
// 初始化全表扫描查询参数
|
||||
Optional.ofNullable(wrapper.matchAllQuery).ifPresent(p -> boolQueryBuilder.must(QueryBuilders.matchAllQuery()));
|
||||
@ -66,6 +67,63 @@ public class WrapperProcessor {
|
||||
return searchSourceBuilder;
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化将树参数转换为BoolQueryBuilder
|
||||
*
|
||||
* @param paramList 参数列表
|
||||
* @param entityClass 实体类
|
||||
*/
|
||||
private static BoolQueryBuilder initBoolQueryBuilder(List<Param> paramList, Class<?> entityClass) {
|
||||
// 建树
|
||||
List<Param> rootList = paramList.stream().filter(p -> Objects.isNull(p.getParentId())).collect(Collectors.toList());
|
||||
TreeBuilder treeBuilder = new TreeBuilder(rootList, paramList);
|
||||
List<Param> tree = (List<Param>) treeBuilder.build();
|
||||
BoolQueryBuilder rootBool = QueryBuilders.boolQuery();
|
||||
|
||||
// 遍历,对森林的每个根节点递归封装
|
||||
tree.forEach(root -> setBool(rootBool, root));
|
||||
return rootBool;
|
||||
}
|
||||
|
||||
private static void setBool(BoolQueryBuilder bool, Param param) {
|
||||
List<Param> children = (List<Param>) param.getChildren();
|
||||
switch (param.getQueryTypeEnum()) {
|
||||
case TERM_QUERY:
|
||||
bool.must(QueryBuilders.termQuery(param.getColumn(), param.getVal()).boost(param.getBoost()));
|
||||
break;
|
||||
case AND_MUST:
|
||||
bool.must(getChildrenBool(children, QueryBuilders.boolQuery()));
|
||||
break;
|
||||
case FILTER:
|
||||
bool.filter(getChildrenBool(children, QueryBuilders.boolQuery()));
|
||||
break;
|
||||
case MUST_NOT:
|
||||
bool.mustNot(getChildrenBool(children, QueryBuilders.boolQuery()));
|
||||
break;
|
||||
case OR_SHOULD:
|
||||
bool.should(getChildrenBool(children, QueryBuilders.boolQuery()));
|
||||
break;
|
||||
default:
|
||||
throw ExceptionUtils.eee("非法参数类型");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 递归获取子节点的bool
|
||||
*
|
||||
* @param paramList 子节点参数列表
|
||||
* @param builder 新的根bool
|
||||
* @return 子节点bool合集, 统一封装至入参builder中
|
||||
*/
|
||||
private static BoolQueryBuilder getChildrenBool(List<Param> paramList, BoolQueryBuilder builder) {
|
||||
if (CollectionUtils.isEmpty(paramList)) {
|
||||
return builder;
|
||||
}
|
||||
paramList.forEach(param -> setBool(builder, param));
|
||||
return builder;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 初始化BoolQueryBuilder 整个框架的核心
|
||||
*
|
||||
@ -226,7 +284,7 @@ public class WrapperProcessor {
|
||||
if (GlobalConfigCache.getGlobalConfig().getDbConfig().isEnableTrackTotalHits()) {
|
||||
searchSourceBuilder.trackTotalHits(Boolean.TRUE);
|
||||
}
|
||||
|
||||
|
||||
return searchSourceBuilder;
|
||||
}
|
||||
|
||||
|
||||
@ -97,44 +97,6 @@ public interface Compare<Children, R> extends Serializable {
|
||||
*/
|
||||
Children eq(boolean condition, String column, Object val, Float boost);
|
||||
|
||||
default Children ne(R column, Object val) {
|
||||
return ne(true, column, val);
|
||||
}
|
||||
|
||||
default Children ne(R column, Object val, Float boost) {
|
||||
return ne(true, column, val, boost);
|
||||
}
|
||||
|
||||
default Children ne(boolean condition, R column, Object val) {
|
||||
return ne(condition, column, val, DEFAULT_BOOST);
|
||||
}
|
||||
|
||||
default Children ne(String column, Object val) {
|
||||
return ne(true, column, val);
|
||||
}
|
||||
|
||||
default Children ne(String column, Object val, Float boost) {
|
||||
return ne(true, column, val, boost);
|
||||
}
|
||||
|
||||
default Children ne(boolean condition, String column, Object val) {
|
||||
return ne(condition, column, val, DEFAULT_BOOST);
|
||||
}
|
||||
|
||||
default Children ne(boolean condition, R column, Object val, Float boost) {
|
||||
return ne(condition, FieldUtils.getFieldName(column), val, boost);
|
||||
}
|
||||
|
||||
/**
|
||||
* 不等于
|
||||
*
|
||||
* @param condition 条件
|
||||
* @param column 列
|
||||
* @param val 值
|
||||
* @param boost 权重值
|
||||
* @return 泛型
|
||||
*/
|
||||
Children ne(boolean condition, String column, Object val, Float boost);
|
||||
|
||||
default Children match(R column, Object val) {
|
||||
return match(true, column, val);
|
||||
@ -618,45 +580,6 @@ public interface Compare<Children, R> extends Serializable {
|
||||
Children prefixQuery(boolean condition, String column, String prefix, Float boost);
|
||||
|
||||
|
||||
default Children notMatch(R column, Object val) {
|
||||
return notMatch(true, column, val);
|
||||
}
|
||||
|
||||
default Children notMatch(R column, Object val, Float boost) {
|
||||
return notMatch(true, column, val, boost);
|
||||
}
|
||||
|
||||
default Children notMatch(boolean condition, R column, Object val) {
|
||||
return notMatch(condition, column, val, DEFAULT_BOOST);
|
||||
}
|
||||
|
||||
default Children notMatch(String column, Object val) {
|
||||
return notMatch(true, column, val);
|
||||
}
|
||||
|
||||
default Children notMatch(String column, Object val, Float boost) {
|
||||
return notMatch(true, column, val, boost);
|
||||
}
|
||||
|
||||
default Children notMatch(boolean condition, String column, Object val) {
|
||||
return notMatch(condition, column, val, DEFAULT_BOOST);
|
||||
}
|
||||
|
||||
default Children notMatch(boolean condition, R column, Object val, Float boost) {
|
||||
return notMatch(condition, FieldUtils.getFieldName(column), val, boost);
|
||||
}
|
||||
|
||||
/**
|
||||
* NOT MATCH 分词不匹配
|
||||
*
|
||||
* @param condition 条件
|
||||
* @param column 列
|
||||
* @param val 值
|
||||
* @param boost 权重
|
||||
* @return 泛型
|
||||
*/
|
||||
Children notMatch(boolean condition, String column, Object val, Float boost);
|
||||
|
||||
default Children gt(R column, Object val) {
|
||||
return gt(true, column, val);
|
||||
}
|
||||
@ -936,44 +859,6 @@ public interface Compare<Children, R> extends Serializable {
|
||||
*/
|
||||
Children like(boolean condition, String column, Object val, Float boost);
|
||||
|
||||
default Children notLike(R column, Object val) {
|
||||
return notLike(true, column, val);
|
||||
}
|
||||
|
||||
default Children notLike(R column, Object val, Float boost) {
|
||||
return notLike(true, column, val, boost);
|
||||
}
|
||||
|
||||
default Children notLike(boolean condition, R column, Object val) {
|
||||
return notLike(condition, column, val, DEFAULT_BOOST);
|
||||
}
|
||||
|
||||
default Children notLike(String column, Object val) {
|
||||
return notLike(true, column, val);
|
||||
}
|
||||
|
||||
default Children notLike(String column, Object val, Float boost) {
|
||||
return notLike(true, column, val, boost);
|
||||
}
|
||||
|
||||
default Children notLike(boolean condition, String column, Object val) {
|
||||
return notLike(condition, column, val, DEFAULT_BOOST);
|
||||
}
|
||||
|
||||
default Children notLike(boolean condition, R column, Object val, Float boost) {
|
||||
return notLike(condition, FieldUtils.getFieldName(column), val, boost);
|
||||
}
|
||||
|
||||
/**
|
||||
* NOT LIKE
|
||||
*
|
||||
* @param condition 条件
|
||||
* @param column 列
|
||||
* @param val 值
|
||||
* @param boost 权重
|
||||
* @return 泛型
|
||||
*/
|
||||
Children notLike(boolean condition, String column, Object val, Float boost);
|
||||
|
||||
default Children likeLeft(R column, Object val) {
|
||||
return likeLeft(true, column, val, DEFAULT_BOOST);
|
||||
|
||||
@ -39,101 +39,101 @@ public class EsQueryTypeUtil {
|
||||
public static void addQueryByType(BoolQueryBuilder boolQueryBuilder, Integer attachType, boolean enableMust2Filter,
|
||||
BaseEsParam.FieldValueModel model, EntityInfo entityInfo, GlobalConfig.DbConfig dbConfig) {
|
||||
|
||||
Integer queryType = model.getEsQueryType();
|
||||
Object value = model.getValue();
|
||||
Float boost = model.getBoost();
|
||||
String path = model.getPath();
|
||||
Integer originalAttachType = model.getOriginalAttachType();
|
||||
String field = model.getField();
|
||||
// 自定义字段名称及驼峰和嵌套字段名称的处理
|
||||
if (StringUtils.isBlank(path)) {
|
||||
field = FieldUtils.getRealField(field, entityInfo.getMappingColumnMap(), dbConfig);
|
||||
} else {
|
||||
// 嵌套或父子类型
|
||||
field = FieldUtils.getRealField(field, entityInfo.getNestedMappingColumnMapByPath(path), dbConfig);
|
||||
}
|
||||
|
||||
// 封装查询参数
|
||||
if (Objects.equals(queryType, EsQueryTypeEnum.TERM_QUERY.getType())) {
|
||||
// 封装精确查询参数
|
||||
TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery(field, value).boost(boost);
|
||||
setQueryBuilder(boolQueryBuilder, attachType, originalAttachType, enableMust2Filter, termQueryBuilder);
|
||||
} else if (Objects.equals(queryType, EsQueryTypeEnum.TERMS_QUERY.getType())) {
|
||||
// 此处兼容由or转入shouldList的in参数
|
||||
Collection<?> values = Objects.isNull(value) ? model.getValues() : (Collection<?>) value;
|
||||
TermsQueryBuilder termsQueryBuilder = QueryBuilders.termsQuery(field, values).boost(boost);
|
||||
setQueryBuilder(boolQueryBuilder, attachType, originalAttachType, enableMust2Filter, termsQueryBuilder);
|
||||
} else if (Objects.equals(queryType, EsQueryTypeEnum.MATCH_PHRASE.getType())) {
|
||||
// 封装模糊分词查询参数(分词必须按原关键词顺序)
|
||||
MatchPhraseQueryBuilder matchPhraseQueryBuilder = QueryBuilders.matchPhraseQuery(field, value).boost(boost);
|
||||
setQueryBuilder(boolQueryBuilder, attachType, originalAttachType, enableMust2Filter, matchPhraseQueryBuilder);
|
||||
} else if (Objects.equals(queryType, EsQueryTypeEnum.MATCH_PHRASE_PREFIX.getType())) {
|
||||
MatchPhrasePrefixQueryBuilder matchPhrasePrefixQueryBuilder = QueryBuilders.matchPhrasePrefixQuery(field, value)
|
||||
.maxExpansions((Integer) model.getExt()).boost(boost);
|
||||
setQueryBuilder(boolQueryBuilder, attachType, originalAttachType, enableMust2Filter, matchPhrasePrefixQueryBuilder);
|
||||
} else if (Objects.equals(queryType, EsQueryTypeEnum.PREFIX_QUERY.getType())) {
|
||||
PrefixQueryBuilder prefixQueryBuilder = QueryBuilders.prefixQuery(field, value.toString()).boost(boost);
|
||||
setQueryBuilder(boolQueryBuilder, attachType, originalAttachType, enableMust2Filter, prefixQueryBuilder);
|
||||
} else if (Objects.equals(queryType, EsQueryTypeEnum.QUERY_STRING_QUERY.getType())) {
|
||||
QueryStringQueryBuilder queryStringQueryBuilder = QueryBuilders.queryStringQuery(value.toString()).boost(boost);
|
||||
setQueryBuilder(boolQueryBuilder, attachType, originalAttachType, enableMust2Filter, queryStringQueryBuilder);
|
||||
} else if (Objects.equals(queryType, EsQueryTypeEnum.MATCH_QUERY.getType())) {
|
||||
// 封装模糊分词查询参数(可无序)
|
||||
MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery(field, value).boost(boost);
|
||||
if (StringUtils.isBlank(path)) {
|
||||
setQueryBuilder(boolQueryBuilder, attachType, originalAttachType, enableMust2Filter, matchQueryBuilder);
|
||||
} else {
|
||||
// 嵌套类型及父子类型处理
|
||||
path = FieldUtils.getRealField(path, entityInfo.getMappingColumnMap(), dbConfig);
|
||||
if (JoinTypeEnum.NESTED.equals(model.getExt())) {
|
||||
matchQueryBuilder = QueryBuilders.matchQuery(path + PATH_FIELD_JOIN + field, value).boost(boost);
|
||||
NestedQueryBuilder nestedQueryBuilder = QueryBuilders.nestedQuery(path, matchQueryBuilder, (ScoreMode) model.getScoreMode());
|
||||
setQueryBuilder(boolQueryBuilder, attachType, originalAttachType, enableMust2Filter, nestedQueryBuilder);
|
||||
} else if (JoinTypeEnum.HAS_CHILD.equals(model.getExt())) {
|
||||
HasChildQueryBuilder hasChildQueryBuilder = new HasChildQueryBuilder(path, matchQueryBuilder, (ScoreMode) model.getScoreMode()).boost(boost);
|
||||
setQueryBuilder(boolQueryBuilder, attachType, originalAttachType, enableMust2Filter, hasChildQueryBuilder);
|
||||
} else if (JoinTypeEnum.HAS_PARENT.equals(model.getExt())) {
|
||||
HasParentQueryBuilder hasParentQueryBuilder = new HasParentQueryBuilder(path, matchQueryBuilder, (Boolean) model.getScoreMode()).boost(boost);
|
||||
setQueryBuilder(boolQueryBuilder, attachType, originalAttachType, enableMust2Filter, hasParentQueryBuilder);
|
||||
} else if (JoinTypeEnum.PARENT_ID.equals(model.getExt())) {
|
||||
ParentIdQueryBuilder parentIdQueryBuilder = new ParentIdQueryBuilder(path, model.getValue().toString()).boost(boost);
|
||||
setQueryBuilder(boolQueryBuilder, attachType, originalAttachType, enableMust2Filter, parentIdQueryBuilder);
|
||||
}
|
||||
}
|
||||
} else if (Objects.equals(queryType, EsQueryTypeEnum.RANGE_QUERY.getType())) {
|
||||
// 封装范围查询参数
|
||||
RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery(field).boost(boost);
|
||||
if (Objects.equals(originalAttachType, EsAttachTypeEnum.GT.getType())) {
|
||||
rangeQueryBuilder.gt(value);
|
||||
} else if (Objects.equals(originalAttachType, EsAttachTypeEnum.LT.getType())) {
|
||||
rangeQueryBuilder.lt(value);
|
||||
} else if (Objects.equals(originalAttachType, EsAttachTypeEnum.GE.getType())) {
|
||||
rangeQueryBuilder.gte(value);
|
||||
} else if (Objects.equals(originalAttachType, EsAttachTypeEnum.LE.getType())) {
|
||||
rangeQueryBuilder.lte(value);
|
||||
}
|
||||
setQueryBuilder(boolQueryBuilder, attachType, originalAttachType, enableMust2Filter, rangeQueryBuilder);
|
||||
} else if (Objects.equals(queryType, EsQueryTypeEnum.EXISTS_QUERY.getType())) {
|
||||
// 封装是否存在查询参数
|
||||
ExistsQueryBuilder existsQueryBuilder = QueryBuilders.existsQuery(field).boost(boost);
|
||||
setQueryBuilder(boolQueryBuilder, attachType, originalAttachType, enableMust2Filter, existsQueryBuilder);
|
||||
} else if (Objects.equals(queryType, EsQueryTypeEnum.WILDCARD_QUERY.getType())) {
|
||||
String query;
|
||||
if (Objects.equals(attachType, EsAttachTypeEnum.LIKE_LEFT.getType())) {
|
||||
query = BaseEsConstants.WILDCARD_SIGN + value;
|
||||
} else if (Objects.equals(attachType, EsAttachTypeEnum.LIKE_RIGHT.getType())) {
|
||||
query = value + BaseEsConstants.WILDCARD_SIGN;
|
||||
} else {
|
||||
query = BaseEsConstants.WILDCARD_SIGN + value + BaseEsConstants.WILDCARD_SIGN;
|
||||
}
|
||||
WildcardQueryBuilder wildcardQueryBuilder = QueryBuilders.wildcardQuery(field, query).boost(boost);
|
||||
setQueryBuilder(boolQueryBuilder, attachType, originalAttachType, enableMust2Filter, wildcardQueryBuilder);
|
||||
} else if (Objects.equals(queryType, EsQueryTypeEnum.INTERVAL_QUERY.getType())) {
|
||||
// 封装between及notBetween
|
||||
RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery(field).boost(boost);
|
||||
rangeQueryBuilder.gte(model.getLeftValue()).lte(model.getRightValue());
|
||||
setQueryBuilder(boolQueryBuilder, attachType, originalAttachType, enableMust2Filter, rangeQueryBuilder);
|
||||
}
|
||||
// Integer queryType = model.getEsQueryType();
|
||||
// Object value = model.getValue();
|
||||
// Float boost = model.getBoost();
|
||||
// String path = model.getPath();
|
||||
// Integer originalAttachType = model.getOriginalAttachType();
|
||||
// String field = model.getField();
|
||||
// // 自定义字段名称及驼峰和嵌套字段名称的处理
|
||||
// if (StringUtils.isBlank(path)) {
|
||||
// field = FieldUtils.getRealField(field, entityInfo.getMappingColumnMap(), dbConfig);
|
||||
// } else {
|
||||
// // 嵌套或父子类型
|
||||
// field = FieldUtils.getRealField(field, entityInfo.getNestedMappingColumnMapByPath(path), dbConfig);
|
||||
// }
|
||||
//
|
||||
// // 封装查询参数
|
||||
// if (Objects.equals(queryType, EsQueryTypeEnum.TERM_QUERY.getType())) {
|
||||
// // 封装精确查询参数
|
||||
// TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery(field, value).boost(boost);
|
||||
// setQueryBuilder(boolQueryBuilder, attachType, originalAttachType, enableMust2Filter, termQueryBuilder);
|
||||
// } else if (Objects.equals(queryType, EsQueryTypeEnum.TERMS_QUERY.getType())) {
|
||||
// // 此处兼容由or转入shouldList的in参数
|
||||
// Collection<?> values = Objects.isNull(value) ? model.getValues() : (Collection<?>) value;
|
||||
// TermsQueryBuilder termsQueryBuilder = QueryBuilders.termsQuery(field, values).boost(boost);
|
||||
// setQueryBuilder(boolQueryBuilder, attachType, originalAttachType, enableMust2Filter, termsQueryBuilder);
|
||||
// } else if (Objects.equals(queryType, EsQueryTypeEnum.MATCH_PHRASE.getType())) {
|
||||
// // 封装模糊分词查询参数(分词必须按原关键词顺序)
|
||||
// MatchPhraseQueryBuilder matchPhraseQueryBuilder = QueryBuilders.matchPhraseQuery(field, value).boost(boost);
|
||||
// setQueryBuilder(boolQueryBuilder, attachType, originalAttachType, enableMust2Filter, matchPhraseQueryBuilder);
|
||||
// } else if (Objects.equals(queryType, EsQueryTypeEnum.MATCH_PHRASE_PREFIX.getType())) {
|
||||
// MatchPhrasePrefixQueryBuilder matchPhrasePrefixQueryBuilder = QueryBuilders.matchPhrasePrefixQuery(field, value)
|
||||
// .maxExpansions((Integer) model.getExt()).boost(boost);
|
||||
// setQueryBuilder(boolQueryBuilder, attachType, originalAttachType, enableMust2Filter, matchPhrasePrefixQueryBuilder);
|
||||
// } else if (Objects.equals(queryType, EsQueryTypeEnum.PREFIX_QUERY.getType())) {
|
||||
// PrefixQueryBuilder prefixQueryBuilder = QueryBuilders.prefixQuery(field, value.toString()).boost(boost);
|
||||
// setQueryBuilder(boolQueryBuilder, attachType, originalAttachType, enableMust2Filter, prefixQueryBuilder);
|
||||
// } else if (Objects.equals(queryType, EsQueryTypeEnum.QUERY_STRING_QUERY.getType())) {
|
||||
// QueryStringQueryBuilder queryStringQueryBuilder = QueryBuilders.queryStringQuery(value.toString()).boost(boost);
|
||||
// setQueryBuilder(boolQueryBuilder, attachType, originalAttachType, enableMust2Filter, queryStringQueryBuilder);
|
||||
// } else if (Objects.equals(queryType, EsQueryTypeEnum.MATCH_QUERY.getType())) {
|
||||
// // 封装模糊分词查询参数(可无序)
|
||||
// MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery(field, value).boost(boost);
|
||||
// if (StringUtils.isBlank(path)) {
|
||||
// setQueryBuilder(boolQueryBuilder, attachType, originalAttachType, enableMust2Filter, matchQueryBuilder);
|
||||
// } else {
|
||||
// // 嵌套类型及父子类型处理
|
||||
// path = FieldUtils.getRealField(path, entityInfo.getMappingColumnMap(), dbConfig);
|
||||
// if (JoinTypeEnum.NESTED.equals(model.getExt())) {
|
||||
// matchQueryBuilder = QueryBuilders.matchQuery(path + PATH_FIELD_JOIN + field, value).boost(boost);
|
||||
// NestedQueryBuilder nestedQueryBuilder = QueryBuilders.nestedQuery(path, matchQueryBuilder, (ScoreMode) model.getScoreMode());
|
||||
// setQueryBuilder(boolQueryBuilder, attachType, originalAttachType, enableMust2Filter, nestedQueryBuilder);
|
||||
// } else if (JoinTypeEnum.HAS_CHILD.equals(model.getExt())) {
|
||||
// HasChildQueryBuilder hasChildQueryBuilder = new HasChildQueryBuilder(path, matchQueryBuilder, (ScoreMode) model.getScoreMode()).boost(boost);
|
||||
// setQueryBuilder(boolQueryBuilder, attachType, originalAttachType, enableMust2Filter, hasChildQueryBuilder);
|
||||
// } else if (JoinTypeEnum.HAS_PARENT.equals(model.getExt())) {
|
||||
// HasParentQueryBuilder hasParentQueryBuilder = new HasParentQueryBuilder(path, matchQueryBuilder, (Boolean) model.getScoreMode()).boost(boost);
|
||||
// setQueryBuilder(boolQueryBuilder, attachType, originalAttachType, enableMust2Filter, hasParentQueryBuilder);
|
||||
// } else if (JoinTypeEnum.PARENT_ID.equals(model.getExt())) {
|
||||
// ParentIdQueryBuilder parentIdQueryBuilder = new ParentIdQueryBuilder(path, model.getValue().toString()).boost(boost);
|
||||
// setQueryBuilder(boolQueryBuilder, attachType, originalAttachType, enableMust2Filter, parentIdQueryBuilder);
|
||||
// }
|
||||
// }
|
||||
// } else if (Objects.equals(queryType, EsQueryTypeEnum.RANGE_QUERY.getType())) {
|
||||
// // 封装范围查询参数
|
||||
// RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery(field).boost(boost);
|
||||
// if (Objects.equals(originalAttachType, EsAttachTypeEnum.GT.getType())) {
|
||||
// rangeQueryBuilder.gt(value);
|
||||
// } else if (Objects.equals(originalAttachType, EsAttachTypeEnum.LT.getType())) {
|
||||
// rangeQueryBuilder.lt(value);
|
||||
// } else if (Objects.equals(originalAttachType, EsAttachTypeEnum.GE.getType())) {
|
||||
// rangeQueryBuilder.gte(value);
|
||||
// } else if (Objects.equals(originalAttachType, EsAttachTypeEnum.LE.getType())) {
|
||||
// rangeQueryBuilder.lte(value);
|
||||
// }
|
||||
// setQueryBuilder(boolQueryBuilder, attachType, originalAttachType, enableMust2Filter, rangeQueryBuilder);
|
||||
// } else if (Objects.equals(queryType, EsQueryTypeEnum.EXISTS_QUERY.getType())) {
|
||||
// // 封装是否存在查询参数
|
||||
// ExistsQueryBuilder existsQueryBuilder = QueryBuilders.existsQuery(field).boost(boost);
|
||||
// setQueryBuilder(boolQueryBuilder, attachType, originalAttachType, enableMust2Filter, existsQueryBuilder);
|
||||
// } else if (Objects.equals(queryType, EsQueryTypeEnum.WILDCARD_QUERY.getType())) {
|
||||
// String query;
|
||||
// if (Objects.equals(attachType, EsAttachTypeEnum.LIKE_LEFT.getType())) {
|
||||
// query = BaseEsConstants.WILDCARD_SIGN + value;
|
||||
// } else if (Objects.equals(attachType, EsAttachTypeEnum.LIKE_RIGHT.getType())) {
|
||||
// query = value + BaseEsConstants.WILDCARD_SIGN;
|
||||
// } else {
|
||||
// query = BaseEsConstants.WILDCARD_SIGN + value + BaseEsConstants.WILDCARD_SIGN;
|
||||
// }
|
||||
// WildcardQueryBuilder wildcardQueryBuilder = QueryBuilders.wildcardQuery(field, query).boost(boost);
|
||||
// setQueryBuilder(boolQueryBuilder, attachType, originalAttachType, enableMust2Filter, wildcardQueryBuilder);
|
||||
// } else if (Objects.equals(queryType, EsQueryTypeEnum.INTERVAL_QUERY.getType())) {
|
||||
// // 封装between及notBetween
|
||||
// RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery(field).boost(boost);
|
||||
// rangeQueryBuilder.gte(model.getLeftValue()).lte(model.getRightValue());
|
||||
// setQueryBuilder(boolQueryBuilder, attachType, originalAttachType, enableMust2Filter, rangeQueryBuilder);
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
@ -153,15 +153,15 @@ public class EsQueryTypeUtil {
|
||||
*/
|
||||
public static void addQueryByType(BoolQueryBuilder boolQueryBuilder, Integer queryType, Integer attachType, Integer originalAttachType,
|
||||
boolean enableMust2Filter, List<String> fields, Object value, Object ext, Integer minShouldMatch, Float boost) {
|
||||
if (Objects.equals(queryType, EsQueryTypeEnum.MULTI_MATCH_QUERY.getType())) {
|
||||
MultiMatchQueryBuilder multiMatchQueryBuilder = QueryBuilders.multiMatchQuery(value, fields.toArray(new String[0])).boost(boost);
|
||||
if (ext instanceof Operator) {
|
||||
Operator operator = (Operator) ext;
|
||||
multiMatchQueryBuilder.operator(operator);
|
||||
multiMatchQueryBuilder.minimumShouldMatch(minShouldMatch + BaseEsConstants.PERCENT);
|
||||
}
|
||||
setQueryBuilder(boolQueryBuilder, attachType, originalAttachType, enableMust2Filter, multiMatchQueryBuilder);
|
||||
}
|
||||
// if (Objects.equals(queryType, EsQueryTypeEnum.MULTI_MATCH_QUERY.getType())) {
|
||||
// MultiMatchQueryBuilder multiMatchQueryBuilder = QueryBuilders.multiMatchQuery(value, fields.toArray(new String[0])).boost(boost);
|
||||
// if (ext instanceof Operator) {
|
||||
// Operator operator = (Operator) ext;
|
||||
// multiMatchQueryBuilder.operator(operator);
|
||||
// multiMatchQueryBuilder.minimumShouldMatch(minShouldMatch + BaseEsConstants.PERCENT);
|
||||
// }
|
||||
// setQueryBuilder(boolQueryBuilder, attachType, originalAttachType, enableMust2Filter, multiMatchQueryBuilder);
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
|
||||
26
easy-es-core/src/main/java/cn/easyes/core/toolkit/Tree.java
Normal file
26
easy-es-core/src/main/java/cn/easyes/core/toolkit/Tree.java
Normal file
@ -0,0 +1,26 @@
|
||||
package cn.easyes.core.toolkit;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 抽象树基类
|
||||
* <p>
|
||||
* Copyright © 2022 xpc1024 All Rights Reserved
|
||||
**/
|
||||
@Data
|
||||
public class Tree {
|
||||
/**
|
||||
* id
|
||||
*/
|
||||
private String id;
|
||||
/**
|
||||
* 父节点id
|
||||
*/
|
||||
private String parentId;
|
||||
/**
|
||||
* 子节点列表
|
||||
*/
|
||||
private List<? extends Tree> children;
|
||||
}
|
||||
@ -0,0 +1,42 @@
|
||||
package cn.easyes.core.toolkit;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class TreeBuilder {
|
||||
/**
|
||||
* 根节点列表
|
||||
*/
|
||||
private List<? extends Tree> rootList;
|
||||
/**
|
||||
* 非根节点列表 当然也可以包含根 不影响
|
||||
*/
|
||||
private List<? extends Tree> bodyList;
|
||||
|
||||
public TreeBuilder(List<? extends Tree> rootList, List<? extends Tree> bodyList) {
|
||||
this.rootList = rootList;
|
||||
this.bodyList = bodyList;
|
||||
}
|
||||
|
||||
public List<? extends Tree> build() {
|
||||
Map<String, String> filterOperated = new HashMap<>(rootList.size() + bodyList.size());
|
||||
//对每个根节点都封装它的孩子节点
|
||||
rootList.forEach(root -> setChildren(root, filterOperated));
|
||||
return rootList;
|
||||
}
|
||||
|
||||
private void setChildren(Tree root, Map<String, String> filterOperated) {
|
||||
List<Tree> children = new ArrayList<>();
|
||||
bodyList.stream()
|
||||
//过滤出未操作过的节点
|
||||
.filter(body -> !filterOperated.containsKey(body.getId()))
|
||||
//过滤出孩子节点
|
||||
.filter(body -> Objects.equals(root.getId(), body.getParentId()))
|
||||
.forEach(body -> {
|
||||
filterOperated.put(body.getId(), root.getId());
|
||||
children.add(body);
|
||||
//递归 对每个孩子节点执行同样操作
|
||||
setChildren(body, filterOperated);
|
||||
});
|
||||
root.setChildren(children);
|
||||
}
|
||||
}
|
||||
@ -221,15 +221,6 @@ public class AllTest {
|
||||
Assertions.assertEquals("测试文档10", documents.get(0).getTitle());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(6)
|
||||
public void testConditionNe() {
|
||||
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
|
||||
wrapper.ne(Document::getTitle, "测试文档10");
|
||||
List<Document> documents = documentMapper.selectList(wrapper);
|
||||
Assertions.assertEquals(21, documents.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(6)
|
||||
public void testConditionGt() {
|
||||
@ -293,15 +284,6 @@ public class AllTest {
|
||||
Assertions.assertEquals(22, documents.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(6)
|
||||
public void testConditionNotLike() {
|
||||
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
|
||||
wrapper.notLike(Document::getTitle, "试文档");
|
||||
List<Document> documents = documentMapper.selectList(wrapper);
|
||||
Assertions.assertEquals(0, documents.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(6)
|
||||
public void testConditionLikeLeft() {
|
||||
@ -499,28 +481,6 @@ public class AllTest {
|
||||
Assertions.assertEquals(1, documents.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(6)
|
||||
public void testConditionOrInner() {
|
||||
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
|
||||
wrapper.in(Document::getStarNum, 1, 2, 3, 4, 10, 11)
|
||||
.and(w -> w.eq(Document::getTitle, "测试文档10").or().eq(Document::getTitle, "测试文档3"));
|
||||
List<Document> documents = documentMapper.selectList(wrapper);
|
||||
Assertions.assertEquals(2, documents.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(6)
|
||||
public void testConditionOrOuter() {
|
||||
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
|
||||
wrapper.eq(Document::getTitle, "测试文档10")
|
||||
.or()
|
||||
.in(Document::getEsId, 1, 2, 3);
|
||||
List<Document> documents = documentMapper.selectList(wrapper);
|
||||
Assertions.assertEquals(4, documents.size());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
@Order(6)
|
||||
public void testPageQuery() {
|
||||
@ -673,16 +633,6 @@ public class AllTest {
|
||||
Assertions.assertEquals(22, documents.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(6)
|
||||
public void testNotMatch() {
|
||||
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
|
||||
wrapper.notMatch(Document::getCreator, "老汉");
|
||||
wrapper.orderByAsc(Document::getStarNum);
|
||||
List<Document> documents = documentMapper.selectList(wrapper);
|
||||
Assertions.assertEquals(0, documents.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(6)
|
||||
public void testMatchPhrase() {
|
||||
@ -747,18 +697,6 @@ public class AllTest {
|
||||
Assertions.assertEquals(22, documents.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(6)
|
||||
public void testWeight() {
|
||||
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
|
||||
wrapper.match(Document::getContent, "更新", 2.0f)
|
||||
.or()
|
||||
.match(Document::getCreator, "老汉");
|
||||
wrapper.sortByScore();
|
||||
List<Document> documents = documentMapper.selectList(wrapper);
|
||||
Assertions.assertEquals("2", documents.get(0).getEsId());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(6)
|
||||
public void testHighLight() {
|
||||
@ -866,4 +804,25 @@ public class AllTest {
|
||||
Assertions.assertTrue(lockDeleted);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
@Order(11)
|
||||
public void testAND() {
|
||||
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
|
||||
wrapper.eq(Document::getCreator, "老汉")
|
||||
.and(a -> a.eq(Document::getContent, "推车")
|
||||
.and(c -> c.eq(Document::getContent, "电车").eq(Document::getContent, "坏了"))
|
||||
.eq(Document::getCreator, "痴汉")
|
||||
.or(b -> b.eq(Document::getStarNum, 888).eq(Document::getCustomField, "不推车")
|
||||
.and(bb -> bb.eq(Document::getStarNum, 888).eq(Document::getCustomField, "不推车")
|
||||
.and(bbb -> bbb.eq(Document::getStarNum, 888).eq(Document::getCustomField, "不推车"))
|
||||
)
|
||||
)
|
||||
)
|
||||
.and(d -> d.eq(Document::getEsId, 666).eq(Document::getGmtCreate, "2023"))
|
||||
;
|
||||
List<Document> documents = documentMapper.selectList(wrapper);
|
||||
System.out.println(documents);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -48,7 +48,7 @@ public class DeleteTest {
|
||||
// System.out.println(successCount);
|
||||
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
|
||||
wrapper.isNotNull(Document::getTitle)
|
||||
.and(w -> w.match(Document::getCustomField, "乌拉").or().eq(Document::getCustomField, "魔鬼"));
|
||||
.or(w -> w.match(Document::getCustomField, "乌拉").eq(Document::getCustomField, "魔鬼"));
|
||||
int successCount = documentMapper.delete(wrapper);
|
||||
System.out.println(successCount);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user