lucene 匹配Hibernate Search查询中非字符串字段的null

xienkqul  于 2023-04-30  发布在  Lucene
关注(0)|答案(1)|浏览(196)

我正在尝试实现以下逻辑的查询:
匹配结果,其中***endDate***高于***now***或***endDate***不存在(即即空)
到目前为止,我能够做的第一部分如下:

dateQuery = queryBuilder.range()
                        .onField("endDate")
                        .above(LocalDateTime.now())
                        .createQuery();

不幸的是,我无法理解第二部分。我尝试过(但失败了):

queryBuilder.bool()
            .must(dateQuery)
            .should(queryBuilder.keyword().onField("endDate")
                                .matching("").createQuery())
            .createQuery();

在Hibernate Search中,有没有什么优雅的方法来检查非字符串字段是否为Null?

cedebl8k

cedebl8k1#

默认情况下,空/空值不被索引,因此查找空/空值不会返回任何结果。
对于Hibernate Search 6及更高版本,考虑exists() predicate predicate ,您可以否定该 predicate 来查找给定字段不存在(没有值)的文档。
第六章6.0 / 6.1:

List<Book> hits = searchSession.search( Book.class )
        .where( f -> f.bool().mustNot( f.exists().field( "endDate" ) ) )
        .fetchHits( 20 );

或者在即将发布的Hibernate Search 6中使用更简单的语法。二:

List<Book> hits = searchSession.search( Book.class )
        .where( f -> f.not( f.exists().field( "endDate" ) ) )
        .fetchHits( 20 );

但是请注意,作为一个纯粹的否定查询,这不会很好地执行。
对于更大的索引,如果您希望获得良好的性能,可以考虑将null作为非null值进行索引。请参见@GenericField(indexNullAs = ...)(其他@*Field注解也可用)。
基本上,您将使用类似于@GenericField(indexNullAs = "9999-12-31T23:59:59.999")的东西来注解您的属性,然后创建一个查询来查找值LocalDateTime.parse("9999-12-31T23:59:59.999"),Hibernate Search将返回所有索引时具有null值的文档。
关于Hibernate Search 5的问题:
您应该在Map中使用@Field(indexNullAs = "...")。在你的例子中,你应该将indexNullAs设置为类似9999-12-31T23:59:59.999(9999年最后一天的最后一毫秒)。
请参阅有关字段的文档。indexNullAs了解更多信息。

相关问题