升级Spring Boot 2.5.6后Spring Data MongoDB的orOperator查询失效如何解决
问题根因
Spring Boot 2.5.6 对应 Spring Data MongoDB 3.2.x 版本,该版本对 Criteria.orOperator() API 的行为做了不兼容调整:
- Spring Data MongoDB 2.x(对应Spring Boot 2.3及以下版本)中,
Criteria.where("title").regex(reg).orOperator(Criteria.where("content").regex(reg))的逻辑等价于{$or:[{title:{$regex:reg}}, {content:{$regex:reg}}]},当前链式调用中已存在的条件会被作为or的第一个子条件处理,符合预期的模糊查询逻辑。 - Spring Data MongoDB 3.x(对应Spring Boot 2.4及以上版本)中,上述写法的逻辑变为
{$and:[{title:{$regex:reg}}, {$or:[{content:{$regex:reg}}]}]},当前已存在的条件会和orOperator包裹的所有条件做AND拼接,完全不符合原有需求,导致返回结果异常。
未使用orOperator的findByTitleContains方法不涉及该API变更,因此运行正常。
解决方案
提供3种兼容新版本的修复方案:
方案1:调整Criteria构造逻辑
不再在已有条件的Criteria实例后链式调用orOperator,直接初始化空Criteria实例,将所有或条件全部传入orOperator,该写法同时兼容新旧版本:Criteria criteria = new Criteria().orOperator( Criteria.where("title").regex(reg), Criteria.where("content").regex(reg) );方案2:使用框架查询派生能力
直接在响应式Repository接口中定义派生查询方法,无需手动构造Criteria,由框架自动解析生成查询语句:public interface PostRepository extends ReactiveMongoRepository<Post, String> { // 调用时两个参数传入相同的正则表达式即可实现原逻辑 Flux<Post> findByTitleRegexOrContentRegex(String titleReg, String contentReg); }方案3:使用原生MongoDB查询注解
直接通过@Query注解写原生查询JSON,完全规避框架API变动影响:public interface PostRepository extends ReactiveMongoRepository<Post, String> { @Query("{$or: [{title: {$regex: ?0}}, {content: {$regex: ?0}}]}") Flux<Post> findByKeyword(String reg); }
内容的提问来源于stack exchange,提问作者Hantsy
相关产品推荐
相关产品推荐

