Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

混合查询getSearchSourceBuilder无法识别wrapper的排序OrderByParam的condition导致null #112

Open
Xiamu-ssr opened this issue Apr 19, 2024 · 0 comments

Comments

@Xiamu-ssr
Copy link

问题描述

这是我的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,但是orderByParamordersort为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。
image
但是却能看到wrapper中有orderByParam属性?
image
随后就是进行到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)

有两种猜想:

  1. 可能是wrapper本身没有正确处理condition。
  2. 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());
        }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant