v2.0-beta

修复一些测试中发现的问题
This commit is contained in:
xpc1024 2023-01-30 16:50:26 +08:00
parent ae60d2da22
commit bba07ca3ec
8 changed files with 112 additions and 99 deletions

View File

@ -59,6 +59,10 @@ public enum EsQueryTypeEnum {
* 前缀匹配
*/
MATCH_PHRASE_PREFIX,
/**
* 查询全部 相当于Mysql中的select * 无where条件 谨慎使用
*/
MATCH_ALL,
/**
* 多字段匹配
*/
@ -102,7 +106,11 @@ public enum EsQueryTypeEnum {
*/
FILTER,
/**
* 或条件相当于MYSQL中的OR
* 或条件相当于MYSQL中的OR 和MP中的or嵌套用法一致
*/
OR_SHOULD;
OR_SHOULD,
/**
* 或条件仅影响紧跟其后的一个条件和MP中的拼接or用法一致
*/
OR;
}

View File

@ -3,10 +3,11 @@ package cn.easyes.common.utils;
import java.util.Objects;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
/**
* 对JDK提供的Optional的自定义,个人认为其高频api ifPresent没有返回用起来不方便
* 避免写过多if-else 提升代码优雅
* 对JDK提供的Optional的自定义增强
* 在一定程度上减少代码中出现的if-else 提升代码优雅
* <p>
* Copyright © 2021 xpc1024 All Rights Reserved
**/
@ -50,6 +51,14 @@ public final class MyOptional<T> {
}
}
public void ifPresent(Consumer<? super T> present, Supplier<?> other) {
if (value != null) {
present.accept(value);
} else {
other.get();
}
}
public <U> MyOptional<U> ifPresent(Function<? super T, ? extends U> present, T otherValue) {
Objects.requireNonNull(present);
if (isPresent())

View File

@ -7,12 +7,8 @@ import cn.easyes.common.utils.*;
import cn.easyes.core.Param;
import cn.easyes.core.biz.AggregationParam;
import cn.easyes.core.biz.BaseSortParam;
import cn.easyes.core.biz.GeoParam;
import cn.easyes.core.biz.OrderByParam;
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 cn.easyes.core.conditions.interfaces.*;
import org.apache.lucene.search.join.ScoreMode;
import org.elasticsearch.common.geo.GeoDistance;
import org.elasticsearch.common.geo.GeoPoint;
@ -37,7 +33,7 @@ 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>, Func<Children, R>, Geo<Children, R> {
implements Compare<Children, R>, Nested<Children, Children>, Func<Children, R>, Join<Children>, Geo<Children, R> {
protected final Children typedThis = (Children) this;
@ -70,20 +66,11 @@ public abstract class AbstractWrapper<T, R, Children extends AbstractWrapper<T,
* 折叠去重字段
*/
protected String distinctField;
/**
* geo相关参数
*/
protected GeoParam geoParam;
/**
* 排序参数列表
*/
protected List<OrderByParam> orderByParams;
/**
* 是否查询全部文档
*/
protected Boolean matchAllQuery;
/**
* 实体对象
*/
@ -164,6 +151,11 @@ public abstract class AbstractWrapper<T, R, Children extends AbstractWrapper<T,
return addNested(condition, OR_SHOULD, consumer);
}
@Override
public Children or(boolean condition) {
return addParam(condition, OR, null, null, null);
}
@Override
public Children must(boolean condition, Consumer<Children> consumer) {
return addNested(condition, AND_MUST, consumer);
@ -217,11 +209,8 @@ public abstract class AbstractWrapper<T, R, Children extends AbstractWrapper<T,
}
@Override
public Children matchAllQuery(boolean condition) {
if (condition) {
this.matchAllQuery = true;
}
return typedThis;
public Children matchAllQuery(boolean condition, Float boost) {
return addParam(condition, MATCH_ALL, null, null, boost);
}
@Override

View File

@ -39,10 +39,6 @@ public class LambdaEsQueryWrapper<T> extends AbstractLambdaQueryWrapper<T, Lambd
* 查询多少条记录
*/
protected Integer size;
/**
* must条件转filter
*/
protected Boolean enableMust2Filter;
/**
* 用户自定义的searchSourceBuilder 用于混合查询
*/
@ -139,14 +135,6 @@ public class LambdaEsQueryWrapper<T> extends AbstractLambdaQueryWrapper<T, Lambd
return typedThis;
}
@Override
public LambdaEsQueryWrapper<T> enableMust2Filter(boolean condition, boolean enable) {
if (condition) {
this.enableMust2Filter = enable;
}
return typedThis;
}
@Override
public LambdaEsQueryWrapper<T> setSearchSourceBuilder(boolean condition, SearchSourceBuilder searchSourceBuilder) {
if (condition) {

View File

@ -59,9 +59,6 @@ public class WrapperProcessor {
// 初始化boolQueryBuilder 参数
BoolQueryBuilder boolQueryBuilder = initBoolQueryBuilder(wrapper.paramList, entityClass);
// 初始化全表扫描查询参数
Optional.ofNullable(wrapper.matchAllQuery).ifPresent(p -> boolQueryBuilder.must(QueryBuilders.matchAllQuery()));
// 初始化searchSourceBuilder 参数
SearchSourceBuilder searchSourceBuilder = initSearchSourceBuilder(wrapper, entityClass);
@ -87,9 +84,9 @@ public class WrapperProcessor {
String realField = FieldUtils.getRealField(param.getColumn(), entityInfo.getMappingColumnMap(), dbConfig);
param.setColumn(realField);
if (ArrayUtils.isNotEmpty(param.getColumns())) {
String[] columns = (String[]) Arrays.stream(param.getColumns())
.map(column -> FieldUtils.getRealField(param.getColumn(), entityInfo.getMappingColumnMap(), dbConfig))
.toArray();
String[] columns = Arrays.stream(param.getColumns())
.map(column -> FieldUtils.getRealField(column, entityInfo.getMappingColumnMap(), dbConfig))
.toArray(String[]::new);
param.setColumns(columns);
}
if (NESTED_MATCH.equals(param.getQueryTypeEnum()) || HAS_CHILD.equals(param.getQueryTypeEnum()) || HAS_PARENT.equals(param.getQueryTypeEnum())) {
@ -156,7 +153,11 @@ public class WrapperProcessor {
setChildrenBool(bool, queryBuilder, parentType);
break;
case MULTI_MATCH:
queryBuilder = QueryBuilders.multiMatchQuery(param.getVal(), param.getColumns()).operator((Operator) param.getExt1()).minimumShouldMatch((String) param.getExt2());
queryBuilder = QueryBuilders.multiMatchQuery(param.getVal(), param.getColumns()).operator((Operator) param.getExt1()).minimumShouldMatch(String.valueOf(param.getExt2()));
setChildrenBool(bool, queryBuilder, parentType);
break;
case MATCH_ALL:
queryBuilder = QueryBuilders.matchAllQuery().boost(param.getBoost());
setChildrenBool(bool, queryBuilder, parentType);
break;
case QUERY_STRING:
@ -192,7 +193,7 @@ public class WrapperProcessor {
setChildrenBool(bool, queryBuilder, parentType);
break;
case TERMS:
queryBuilder = QueryBuilders.termsQuery(param.getColumn(), (Object[]) param.getVal());
queryBuilder = QueryBuilders.termsQuery(param.getColumn(), (Collection<?>) param.getVal());
setChildrenBool(bool, queryBuilder, parentType);
break;
case EXISTS:
@ -204,9 +205,9 @@ public class WrapperProcessor {
setChildrenBool(bool, queryBuilder, parentType);
break;
case GEO_DISTANCE:
GeoDistanceQueryBuilder geoDistance = QueryBuilders.geoDistanceQuery(param.getColumn()).point((GeoPoint) param.getExt2()).boost(param.getBoost());
MyOptional.ofNullable(param.getExt1()).ifPresent(ext1 -> geoDistance.distance((Double) param.getVal(), (DistanceUnit) ext1), geoDistance.distance((String) param.getVal()));
queryBuilder = geoDistance;
GeoDistanceQueryBuilder geoDistanceBuilder = QueryBuilders.geoDistanceQuery(param.getColumn()).point((GeoPoint) param.getExt2()).boost(param.getBoost());
MyOptional.ofNullable(param.getExt1()).ifPresent(ext1 -> geoDistanceBuilder.distance((double) param.getVal(), (DistanceUnit) ext1), () -> geoDistanceBuilder.distance((String) param.getVal()));
queryBuilder = geoDistanceBuilder;
setChildrenBool(bool, queryBuilder, parentType);
break;
case GEO_POLYGON:

View File

@ -360,16 +360,25 @@ public interface Compare<Children, R> extends Serializable {
default Children matchAllQuery() {
return matchAllQuery(true);
return matchAllQuery(true, DEFAULT_BOOST);
}
default Children matchAllQuery(Float boost) {
return matchAllQuery(true, boost);
}
default Children matchAllQuery(boolean condition) {
return matchAllQuery(condition, DEFAULT_BOOST);
}
/**
* 查询全部文档
*
* @param condition 条件
* @param boost 权重值
* @return 泛型
*/
Children matchAllQuery(boolean condition);
Children matchAllQuery(boolean condition, Float boost);
default Children matchPhrasePrefixQuery(R column, Object val) {

View File

@ -116,19 +116,6 @@ public interface Query<Children, T, R> extends Serializable {
Children index(boolean condition, String... indexNames);
default Children enableMust2Filter(boolean enable) {
return enableMust2Filter(true, enable);
}
/**
* must 条件转filter 默认不转换
*
* @param condition 条件
* @param enable 是否开启 true开启 false 不开启 默认不开转换
* @return 泛型
*/
Children enableMust2Filter(boolean condition, boolean enable);
default Children setSearchSourceBuilder(SearchSourceBuilder searchSourceBuilder) {
return setSearchSourceBuilder(true, searchSourceBuilder);
}

View File

@ -14,6 +14,7 @@ import cn.easyes.test.TestEasyEsApplication;
import cn.easyes.test.entity.Document;
import cn.easyes.test.mapper.DocumentMapper;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.geo.GeoDistance;
import org.elasticsearch.common.geo.GeoPoint;
import org.elasticsearch.common.geo.ShapeRelation;
@ -21,6 +22,7 @@ import org.elasticsearch.common.unit.DistanceUnit;
import org.elasticsearch.geometry.Circle;
import org.elasticsearch.geometry.Point;
import org.elasticsearch.geometry.Rectangle;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.aggregations.bucket.terms.ParsedLongTerms;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
@ -34,6 +36,7 @@ import org.elasticsearch.search.sort.GeoDistanceSortBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.junit.jupiter.api.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import javax.annotation.Resource;
@ -53,6 +56,8 @@ import java.util.*;
public class AllTest {
@Resource
private DocumentMapper documentMapper;
@Autowired
private RestHighLevelClient client;
// 1.新增
@Test
@ -62,8 +67,8 @@ public class AllTest {
Document document = new Document();
document.setEsId("1");
document.setTitle("测试文档1");
document.setContent("阿凡达");
document.setCreator("流量");
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");
@ -302,6 +307,17 @@ public class AllTest {
Assertions.assertEquals(1, documents.size());
}
@Test
@Order(6)
public void testConditionExists() {
// exists等价于isNotNull 在es中更推荐此种语法
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
wrapper.exists(Document::getNullField);
List<Document> documents = documentMapper.selectList(wrapper);
Assertions.assertEquals(1, documents.size());
}
@Test
@Order(6)
public void testConditionIn() {
@ -433,17 +449,6 @@ public class AllTest {
Assertions.assertEquals(22, documents.size());
}
@Test
@Order(6)
public void testConditionEnableMust2Filter() {
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
wrapper.match(Document::getCreator, "老汉")
.enableMust2Filter(true);
String source = documentMapper.getSource(wrapper);
System.out.println(source);
Assertions.assertTrue(source.contains("filter"));
}
@Test
@Order(6)
public void testConditionAnd() {
@ -454,6 +459,30 @@ public class AllTest {
Assertions.assertEquals(1, documents.size());
}
@Test
@Order(6)
public void testConditionOr() {
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
wrapper.and(w -> w.in(Document::getStarNum, 1, 2, 3, 4, 10, 11)
.eq(Document::getTitle, "测试文档10")
.match(Document::getCreator, "老汉")
.or(i -> i.eq(Document::getTitle, "测试文档11")));
List<Document> documents = documentMapper.selectList(wrapper);
Assertions.assertEquals(2, documents.size());
}
@Test
@Order(6)
public void testConditionOrInner() {
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
wrapper.and(w -> w.match(Document::getContent, "测试").match(Document::getCreator, "老汉")
.or(i -> i.eq(Document::getStarNum, 12))
);
List<Document> documents = documentMapper.selectList(wrapper);
Assertions.assertEquals(2, documents.size());
}
@Test
@Order(6)
public void testPageQuery() {
@ -697,12 +726,12 @@ public class AllTest {
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
GeoPoint geoPoint = new GeoPoint(41.0, 116.0);
wrapper.geoDistance(Document::getLocation, 168.8, DistanceUnit.KILOMETERS, geoPoint);
GeoDistanceSortBuilder geoDistanceSortBuilder = SortBuilders.geoDistanceSort(FieldUtils.val(Document::getLocation), geoPoint)
.unit(DistanceUnit.KILOMETERS)
.geoDistance(GeoDistance.ARC)
.order(SortOrder.DESC);
wrapper.sort(geoDistanceSortBuilder);
// GeoDistanceSortBuilder geoDistanceSortBuilder = SortBuilders.geoDistanceSort(FieldUtils.val(Document::getLocation), geoPoint)
// .unit(DistanceUnit.KILOMETERS)
// .geoDistance(GeoDistance.ARC)
// .order(SortOrder.DESC);
//
// wrapper.sort(geoDistanceSortBuilder);
List<Document> documents = documentMapper.selectList(wrapper);
Assertions.assertEquals(4, documents.size());
}
@ -767,25 +796,18 @@ 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);
@Order(21)
public void testDSL(){
// 设置检索条件
List<Integer> values = Arrays.asList(2,3);
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
boolQueryBuilder.must(QueryBuilders.termQuery("business_type",1));
boolQueryBuilder.must(QueryBuilders.boolQuery().must(QueryBuilders.termQuery("state",9))
.should(QueryBuilders.boolQuery().must(QueryBuilders.termQuery("state",8)).must(QueryBuilders.termQuery("bidding_sign",1))));
boolQueryBuilder.should(QueryBuilders.boolQuery().must(QueryBuilders.termQuery("business_type",2)).must(QueryBuilders.termsQuery("state",values)));
System.out.println(boolQueryBuilder.toString());
System.out.println();
}
}