【问题标题】:Elastic Search / Hibernate Search : how to code xor operator with query DSL API in java?弹性搜索/休眠搜索:如何在 java 中使用查询 DSL API 编写 xor 运算符?
【发布时间】:2021-11-17 14:19:04
【问题描述】:

我正在使用 hibernate search java API 来生成弹性搜索查询。我在编写 xor 运算符时遇到问题。通常我会写:

private void applyXorOperator(BooleanPredicateClausesStep<?> boolClausesAppender,
                                  BooleanPredicateClausesStep<?> firstBool,
                                  BooleanPredicateClausesStep<?> secondBool) {

        boolClausesAppender.should(
        boolClausesAppender.must(firstBool).mustNot(secondBool));
        boolClausesAppender.should(
                boolClausesAppender.mustNot(firstBool).must(secondBool));
        boolClausesAppender.minimumShouldMatchNumber(1);
    }

我期待的“不是两者”怎么说:

boolClausesAppender.maximumShouldMatchNumber(1);

但 API 中不存在此方法。有什么解决办法吗?

谢谢。

【问题讨论】:

    标签: elasticsearch querydsl hibernate-search


    【解决方案1】:

    根据定义:

    a XOR b <=> (a AND NOT b) OR (NOT a AND b)
    

    所以就这样实现吧:

    private void applyXorOperator(BooleanPredicateClausesStep<?> boolClausesAppender,
                                      BooleanPredicateClausesStep<?> firstBool,
                                      BooleanPredicateClausesStep<?> secondBool) {
        SearchPredicate a = firstBool.toPredicate();
        SearchPredicate b = secondBool.toPredicate();
    
        boolClausesAppender.should(f -> f.bool()
             // a AND NOT b
             .should(f.bool().must(a).mustNot(b))
             // OR (NOT a AND b)
             .should(f.bool().mustNot(a).must(b)));
    }
    

    编辑:顺便说一句,您不需要 first/second 是布尔谓词。这也可以,而且看起来更简单:

    private void applyXorOperator(BooleanPredicateClausesStep<?> boolClausesAppender,
                                      PredicateFinalStep first,
                                      PredicateFinalStep second) {
        SearchPredicate a = first.toPredicate();
        SearchPredicate b = second.toPredicate();
    
        boolClausesAppender.should(f -> f.bool()
             // a AND NOT b
             .should(f.bool().must(a).mustNot(b))
             // OR (NOT a AND b)
             .should(f.bool().mustNot(a).must(b)));
    }
    

    【讨论】:

    • 非常感谢您的回答。没错我做错了,公式已经包含“不是两者”,我什么都不知道;)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-31
    • 2019-09-07
    • 2020-10-11
    相关资源
    最近更新 更多