Hibernate Search 6 BooleanPredicateClausesStep空判断等效方法
Hibernate Search 6 判断布尔谓词为空的实现方案
BooleanPredicateClausesStep 没有提供与Hibernate Search 5中isEmpty()等效的内置方法,这是版本API设计的主动调整,并非功能遗漏。Hibernate Search 6不再对外暴露布尔谓词的内部子句状态,相关判断逻辑需要业务侧自行维护,同时也避免了框架内置判断可能出现的误判问题——比如Hibernate Search 5中如果向BooleanJunction添加了嵌套的空布尔子句,isEmpty()会错误返回false。
推荐实现方案
最稳妥、无版本兼容风险的方式是自行维护有效子句计数,适配现有代码逻辑的改造量极小:
- 改造原有的子句添加方法,让其返回布尔值,标识本次操作是否真的向布尔谓词中添加了有效子句
- 在构建布尔谓词的流程中维护一个计数器,仅当子句真实添加成功时累加计数
- 最终通过计数器是否为0,判断当前布尔谓词是否为空,为空则返回
null供上层逻辑跳过无效谓词
适配Hibernate Search 6.1.5.Final的改造后代码示例:
public SearchPredicate buildProbableVendorNamesPredicate(SearchPredicateFactory pf, Set<String> vendorNames) { BooleanPredicateClausesStep<?> namesBool = pf.bool(); int validClauseCounter = 0; vendorNames.forEach(name -> { // 原addProbableVendorNameBool方法改为返回boolean:有效添加返回true,无效场景(停用词/归一化后无内容等)返回false if (addProbableVendorNameBool(pf, namesBool, name)) { validClauseCounter++; } }); return validClauseCounter == 0 ? null : namesBool.toPredicate(); }
对应的addProbableVendorNameBool方法改造逻辑:
- 方法返回值从
void调整为boolean - 方法内部前置校验逻辑:如果传入的名称为停用词、经分析/归一化后无有效分词、生成的子句无实际查询意义,直接返回
false,不执行任何向namesBool添加子句的操作 - 只有当真实调用
namesBool.must()/should()/filter()/mustNot()等方法完成子句添加后,才返回true
不推荐的做法
- 不要通过反射读取
BooleanPredicateClausesStep实例的内部字段判断子句数量:不同小版本的内部字段名、数据结构可能随时调整,版本升级时极易出现不可预期的故障 - 不要先调用
toPredicate()生成谓词实例再尝试反向判断状态:空布尔谓词生成后会被框架在查询组装阶段静默忽略,没有公开API可以反向判断其是否为空,且提前生成无效谓词会产生不必要的性能开销
截止目前最新的Hibernate Search 6稳定版本,官方依然没有计划新增内置的
isEmpty()方法,核心原因是框架无法感知业务层面定义的「有效子句」标准,内置判断无法覆盖类似停用词、无效嵌套子句等自定义场景,交给业务侧维护计数的方式灵活性和准确率更高。
内容的提问来源于stack exchange,提问作者Rick Gagne
相关产品推荐
相关产品推荐

