java 在Hibernate搜索6中,BooleanJunction#是空等价项布尔 predicate 子句步骤

omvjsjqw  于 2023-02-14  发布在  Java
关注(0)|答案(1)|浏览(144)

Hibernate Search 5的BooleanJunction有一个有用的isEmpty()方法,你可以确定是否有子句存在,这有助于构建上游查询,如果一个特定的BooleanJunction为空,它将不会提供所需的结果,或者将改变我们的查询。
在Hibernate Search 6中,BooleanPredicateClausesStep的等价物是什么?我没有看到,那么是否有其他方法可以确定BooleanPredicateClausesStep是否为空或其中不包含子句?
提供一些示例代码进行说明。
Hibernate搜索5.10.7.最终版:

public Query buildProbableVendorNamesQuery(FullTextSession fts, QueryBuilder qb, Set<String> vendorNames) {
            BooleanJunction namesBool = qb.bool();

            vendorNames.forEach(name ->
                    addProbableVendorNameBool(fts, qb, namesBool, name)
            );
    
            return namesBool.isEmpty() ? null : namesBool.createQuery();
        }

Hibernate搜索6.1.5.最终版:

public SearchPredicate buildProbableVendorNamesPredicate(SearchPredicateFactory pf, Set<String> vendorNames) {
        BooleanPredicateClausesStep namesBool = pf.bool();

        vendorNames.forEach(name ->
                addProbableVendorNameBool(pf, namesBool, name)
        );

        //TODO: How can we know if namesBool is empty so we can return null?
        return namesBool.toPredicate();
    }

namesBool可能为空的原因有很多,其中一个原因是名称本身最终成为一个停用词或被规范化为空,在这种情况下,我们需要通知上游调用者SearchPredicate为空,因此不要尝试在查询中使用它。

fquxozlt

fquxozlt1#

编辑:Hibernate Search 6.2.0.Alpha2在BooleanPredicateOptionsCollector/BooleanPredicateClausesStep上引入了一个hasClause方法,所以您应该使用它。
之前的答案:
在Hibernate Search 6.2之前,没有对等的功能。
同时,您可以将List传递给addProbableVendorNameBool作为一种变通方法。虽然不是很漂亮,但它会起作用:

public SearchPredicate buildProbableVendorNamesPredicate(SearchPredicateFactory pf, Set<String> vendorNames) {
        List<SearchPredicate> clauses = new ArrayList();

        vendorNames.forEach(name ->
                addProbableVendorNameBool(pf, clauses, name)
        );

        if (clauses.isEmpty()) {
            return null;
        }

        BooleanPredicateClausesStep namesBool = pf.bool();
        clauses.forEach(namesBool::should);
        return namesBool.toPredicate();
    }

    private void addProbableVendorNameBool(SearchPredicateFactory pf, List<SearchPredicate> clauses, String name) {
        ...
    }

或者,如果你可以修改addProbableVendorNameBool,使其返回一个 predicate (例如,如果需要,让它创建自己的布尔 predicate )或null

public SearchPredicate buildProbableVendorNamesPredicate(SearchPredicateFactory pf, Set<String> vendorNames) {
        List<SearchPredicate> clauses = vendorNames.stream()
                .map(name -> buildProbableVendorSingleNamePredicate(pf, name))
                .filter(Objects::nonNull)
                .collect(Collectors.toList());

        if (clauses.isEmpty()) {
            return null;
        }

        BooleanPredicateClausesStep namesBool = pf.bool();
        clauses.forEach(namesBool::should);
        return namesBool.toPredicate();
    }

    private SearchPredicate buildProbableVendorSingleNamePredicate(SearchPredicateFactory pf, String name) {
        ...
        return <something or null>;
    }

相关问题