我试图对数据库中为null的属性使用@IndexedEmbedded
的indexNullAs
属性:
...
@Indexed
public class DocVersion implements Serializable {
...
@IndexedEmbedded(indexNullAs = "valid")
@OneToOne(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "rule_id")
private ValidityRule validityRule;
...
}
在数据库中,我有两条记录,一条具有与该记录关联的
validityRule
,另一条为空。这是我为休眠搜索构建的查询的一部分:
FullTextQueryImpl(-(+document2.docType.documentType:FOLDER) +(+document2.eDocState:ACTIVE) +(document2.docType.documentType:ACCOUNTSTATEMENT) +(+validityRule.validFrom:[* TO 0000020190601] +validityRule.validTo:[0000020190701 TO *] validityRule:valid))
这仅返回一条记录,该记录与
validityRule
关联并符合日期条件。我的问题是,它不会返回未设置validityRule的第二行。
我理解此
indexNullAs
,因为当未设置db字段时,它应该变为“有效”字符串。您可以在查询中看到它吗?那么,为什么我没有得到结果集中的第二行呢?我究竟做错了什么?
我已经从dist中删除了所有索引,并且程序在每次运行时都在重新索引记录。
hibernate-search-orm:5.10.4。最后
感谢您的解释。
最佳答案
问题出在查询的这一部分:
+validityRule.validFrom:[* TO 0000020190601] +validityRule.validTo:[0000020190701 TO *] validityRule:valid
您在这里说的是:
validityRule.validFrom
必须低于0000020190601validityRule.validTo
必须在0000020190701以上(可选)
validityRule
应该等于valid
,在这种情况下,文档的分数应该稍高。这大致转换为以下布尔表达式:
(
validityRule.validFrom:[* TO 0000020190601]
AND validityRule.validTo:[0000020190701 TO *]
)
“ SHOULD”子句未出现在其中,因为它是可选的。它不影响匹配,仅影响得分。
这里重要的是“ MUST” /“ SHOULD”不直接等效于布尔运算符“ AND” /“ OR”:它们具有自己的含义。
根据经验,如果要在全文查询中实现“ AND” /“ OR”:
对于“ AND”,仅使用带有“ MUST”子句的布尔查询。
对于“ OR”,仅使用带有“ SHOULD”子句的布尔查询。
根据需要嵌套布尔查询,以组合“ AND”和“ OR”。可以将布尔查询视为传统布尔表达式中的括号:它们可以防止“ AND”运算符与“ OR”运算符混淆。
除非您知道自己在做什么,否则切勿在同一个布尔查询中混合使用“ MUST”和“ SHOULD”。
在您的情况下,您将需要两个级别的布尔查询:
( // parent boolean query implementing "OR"
( // First "SHOULD" clause: a boolean query implementing "AND"
+validityRule.validFrom:[* TO 0000020190601] // "MUST" clause
+validityRule.validTo:[0000020190701 TO *] // "MUST" clause
)
validityRule:valid // Second "SHOULD" clause
)