easy-es
easy-es copied to clipboard
混合查询getSearchSourceBuilder无法识别wrapper的排序OrderByParam的condition导致null
问题描述
这是我的controller
代码
@PostMapping("/list")
public EsPageInfo<CourseBase> pageList(
@RequestBody CourseQueryBo bo
) {
return courseService.pageList(bo, bo.getPageNum(), bo.getPageSize());
}
然后是post的参数CourseQueryBo
@Data
public class CourseQueryBo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 课程名称
*/
private String name;
/**
* 大分类
*/
private String mt;
/**
* 小分类
*/
private String st;
/**
* 是否收费
*/
private Boolean charge;
/**
* 是否热门
*/
private Boolean isHot;
private OrderByParam orderByParam;
private Integer pageNum;
private Integer pageSize;
}
当传来的参数中orderByParam
不为null,但是orderByParam
的order
和sort
为null。
我的Service代码如下,可以看到我的wrapper中orderBy添加了condition来保证orderByParam
必需有效。
LambdaEsQueryWrapper<CourseBase> queryWrapper = new LambdaEsQueryWrapper<>();
queryWrapper
//大分类选择全部时,参数为空,不筛选
.eq(StringUtils.isNotEmpty(bo.getMt()), CourseBase::getMt, bo.getMt(), CourseQueryBoostBo.mt)
//小分类选择全部时,参数为空,不筛选
.eq(StringUtils.isNotEmpty(bo.getSt()), CourseBase::getSt, bo.getSt(), CourseQueryBoostBo.st)
//付费规则全选时,参数为空,不筛选
.eq(bo.getCharge() != null, CourseBase::getCharge, bo.getCharge(), CourseQueryBoostBo.charge)
//付费规则全选时,参数为空,不筛选
.eq(bo.getIsHot() != null, CourseBase::getIsHot, bo.getIsHot(), CourseQueryBoostBo.isHot)
//搜索框名称为空时,不筛选
.match(StringUtils.isNotEmpty(bo.getName()), CourseBase::getName, bo.getName(), CourseQueryBoostBo.name)
.orderBy(bo.getOrderByParam()!=null && bo.getOrderByParam().getOrder()!=null && bo.getOrderByParam().getSort()!=null, bo.getOrderByParam());
SearchSourceBuilder searchSourceBuilder = courseBaseMapper.getSearchSourceBuilder(queryWrapper);
然后开始debug,如图是service收到的参数,可以看到orderByParam
的order和sort都是null。
但是却能看到
wrapper
中有orderByParam
属性?
随后就是进行到
SearchSourceBuilder searchSourceBuilder = courseBaseMapper.getSearchSourceBuilder(queryWrapper);
这一步报错,报错如下,CourseServiceImpl.java:57
指的就是getSearchSourceBuilder行。
2024-04-19 14:02:28 [XNIO-1 task-18] ERROR o.d.c.s.h.GlobalExceptionHandler
- 请求地址'/es/list',发生未知异常.
java.lang.reflect.UndeclaredThrowableException: null
at jdk.proxy2/jdk.proxy2.$Proxy162.getSearchSourceBuilder(Unknown Source)
at org.dromara.es.service.impl.CourseServiceImpl.pageList(CourseServiceImpl.java:57)
at org.dromara.es.controller.CourseController.pageList(CourseController.java:58)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:150)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:118)
Caused by: java.lang.IllegalArgumentException: fieldName must not be null
at org.elasticsearch.search.sort.FieldSortBuilder.<init>(FieldSortBuilder.java:130)
at org.dromara.easyes.core.core.WrapperProcessor.lambda$setSort$16(WrapperProcessor.java:449)
at java.base/java.util.Collections$SingletonList.forEach(Collections.java:4966)
at org.dromara.easyes.core.core.WrapperProcessor.setSort(WrapperProcessor.java:447)
at org.dromara.easyes.core.core.WrapperProcessor.initSearchSourceBuilder(WrapperProcessor.java:332)
at org.dromara.easyes.core.core.WrapperProcessor.buildSearchSourceBuilder(WrapperProcessor.java:61)
at org.dromara.easyes.core.core.BaseEsMapperImpl.getSearchSourceBuilder(BaseEsMapperImpl.java:224)
有两种猜想:
- 可能是wrapper本身没有正确处理condition。
- getSearchSourceBuilder时没有正确处理condition
暂行解决方法
手动判断
LambdaEsQueryWrapper<CourseBase> queryWrapper = new LambdaEsQueryWrapper<>();
queryWrapper
//大分类选择全部时,参数为空,不筛选
.eq(StringUtils.isNotEmpty(bo.getMt()), CourseBase::getMt, bo.getMt(), CourseQueryBoostBo.mt)
//小分类选择全部时,参数为空,不筛选
.eq(StringUtils.isNotEmpty(bo.getSt()), CourseBase::getSt, bo.getSt(), CourseQueryBoostBo.st)
//付费规则全选时,参数为空,不筛选
.eq(bo.getCharge() != null, CourseBase::getCharge, bo.getCharge(), CourseQueryBoostBo.charge)
//付费规则全选时,参数为空,不筛选
.eq(bo.getIsHot() != null, CourseBase::getIsHot, bo.getIsHot(), CourseQueryBoostBo.isHot)
//搜索框名称为空时,不筛选
.match(StringUtils.isNotEmpty(bo.getName()), CourseBase::getName, bo.getName(), CourseQueryBoostBo.name);
if (bo.getOrderByParam()!=null && bo.getOrderByParam().getOrder()!=null && bo.getOrderByParam().getSort()!=null){
//排序选择综合时,OrderByParam为空,不参与排序
queryWrapper.orderBy(bo.getOrderByParam());
}