问题描述
我在下面选择了SQL查询
SELECT * FROM data_entity WHERE
agreement_number='9999' AND use_type='xxxx' AND end_date IS NOT NULL AND end_date <= '2022-05-03'::date
OR (rib='1111111' AND iban='22222222');
我想使用休眠搜索将其转换为查询,我尝试使用以下查询,但是它给我的结果不正确,有人可以看到查询有问题吗?
@Entity
@Indexed
public class DataEntity {
@Id
private String id;
@Field
private String agreementNumber;
@Field
private String useType;
@Field
@DateBridge(resolution = Resolution.DAY)
private Date endDate;
@Field
private String rib;
@Field
private String iban;
}
org.apache.lucene.search.Query firstQuery = getQuery().bool()
.must(getQuery().bool()
.must(getQuery().keyword().onField("agreementNumber").matching(agreementNumber).createquery())
.must(getQuery().keyword().onField("useType").matching(useType).createquery())
.must(getQuery().range().onField("endDate").above(effectiveDate).createquery()).createquery())
.should(getQuery().bool()
.must(getQuery().keyword().onField("rib").matching(rib).createquery())
.must(getQuery().keyword().onField("iban").matching(iban).createquery()).createquery())
.createquery();
解决方法
您在同一布尔查询中使用must
和should
。这可能不会按照您的想法去做。
要模拟布尔AND
,请使用仅包含must
子句的布尔查询。
要模拟布尔OR
,请使用仅包含should
子句的布尔查询。
此外,您正在使用above
比较日期,而SQL查询显然正在查找给定日期之前的日期。
所以,尝试:
org.apache.lucene.search.Query firstQuery = getQuery().bool()
.should(getQuery().bool()
.must(getQuery().keyword().onField("agreementNumber").matching(agreementNumber).createQuery())
.must(getQuery().keyword().onField("useType").matching(useType).createQuery())
.must(getQuery().range().onField("endDate").below(effectiveDate).createQuery()).createQuery())
.should(getQuery().bool()
.must(getQuery().keyword().onField("rib").matching(rib).createQuery())
.must(getQuery().keyword().onField("iban").matching(iban).createQuery()).createQuery())
.createQuery();
在相关说明中,您可能还想禁用对代表代码的字段的分析,例如agreementNumber
,rib
等。否则,最终可能会得到比预期更多的匹配项。另外,如果您需要一定程度的宽大处理,但又不需要全面的分析,则可以依靠normalizers
:https://docs.jboss.org/hibernate/search/5.11/reference/en-US/html_single/#section-normalizers
(对于其他阅读本文的人,“ RIB”是法国银行帐户标识符,而不是一块肉)