【问题标题】:Hibernate Search 5.11 indexNullAs does not work休眠搜索 5.11 indexNullAs 不起作用
【发布时间】:2019-06-24 15:40:14
【问题描述】:

我的索引实体中有一个可为空的列,我想过滤掉相应字段中具有null 的实体。我使用 Elasticsearch 作为索引管理器。

@Field(analyze = Analyze.NO, indexNullAs = "2999-12-31")
@Column(name = "nullable_date")
private LocalDate nullableDate;

我在Field 注释中使用了indexNullAs 属性,如果我正确理解文档,null 值应替换为索引中的"2999-12-31" 值。 但是在 Elasticsearch 中,这个字段有一个实际的 null 值,而不是我在注释中指定的 "2999-12-31" 字符串:

"nullableDate": null,

此字段位于根索引实体中(不是 IndexedEmbedded 实体,因此不是这个问题https://hibernate.atlassian.net/browse/HSEARCH-2389)。

我尝试了类似+nullableDate:null 的查询并将其发送到createFullTextQuery 方法,但我从Elasticsearch 收到failed to parse date field [null] with format [strict_date||yyyyyyyyy-MM-dd] 错误。我也尝试过像 +nullableDate:2999-12-31 这样的查询,显然我得到了空结果(因为字段在 Elastic 中有 null 值)。

这是否意味着indexNullAs 无法正常工作(是https://hibernate.atlassian.net/browse/HSEARCH-3099 问题吗?)还是我以错误的方式使用它? 谢谢。

【问题讨论】:

    标签: hibernate elasticsearch lucene hibernate-search


    【解决方案1】:

    我认为问题在于您的查询,而不是索引。 indexNullAs 确实适用于 LocalDate 上的 Elasticsearch(我只是仔细检查过)。

    您如何构建查询?如果您使用的是indexNullAs,您可能应该使用我们的 DSL。

    无论如何,这是可行的:

            QueryBuilder queryBuilder = session.getSearchFactory().buildQueryBuilder().forEntity( MyEntity.class ).get();
            Query luceneQuery = queryBuilder.keyword()
                    .onField( "nullableDate" )
                    .matching( LocalDate.of( 2999, Month.DECEMBER, 31 ) )
                    .createQuery();
            result = session.createFullTextQuery( luceneQuery, MyEntity.class ).list();
    

    还有这个:

            QueryBuilder queryBuilder = session.getSearchFactory().buildQueryBuilder().forEntity( MyEntity.class ).get();
            Query luceneQuery = queryBuilder.keyword()
                    .onField( "nullableDate" )
                    .matching( null )
                    .createQuery();
            result = session.createFullTextQuery( luceneQuery, MyEntity.class ).list();
    

    Hibernate Search 发送“null”这一事实是意料之中的,并且实际上是一个特性:它允许在使用投影时正确检索 null。至于索引,由 Hibernate Search 生成并推送到 Elasticsearch 的 Elasticsearch 映射(即模式)应该包括以下内容:

    properties: {
        ...
    
        "nullableDate": {
            "type": "date",
            "format": "yyyyyyyyy-MM-dd",
            "null_value": "2999-12-31"
    
        }
    
        ...
    
    }
    
    

    null_value 部分意味着每当 Elasticsearch 接收到空值时,它会将其索引为“2999-12-31”。这正是您想要的。

    附带说明,HSEARCH-3099 只是提醒我们在 Hibernate Search 6 中添加此功能的任务;完全不影响 5.11。

    【讨论】:

    • 感谢您的回答!实际上,我正在实现一个使用 lucene 查询的 API。我使用QueryParser 将查询字符串解析为org.apache.lucene.search.Query 发送到FullTextEntityManager.createFullTextQuery 方法的对象。我将尝试对您发送的示例进行硬编码以检查它是否正常工作,然后尝试将其映射到相应的查询字符串。
    • 我尝试了使用 DSL 提出的方法,但它给了我空的结果。之后,我在 Elasticsearch 中检查了该字段的模式,得到了这个:"nullableDate": { "type": "date", "format": "strict_date||yyyyyyyyy-MM-dd" }, 所以没有"null_value": 属性。我是否需要添加任何其他配置才能启用它?我有 Elasticsearch 版本 5.6.x
    • 我不得不将 index_schema_management_strategy 更改为 drop-and-create,因此架构已更新。有什么方法可以在不更改index_schema_management_strategy 属性的情况下执行架构更新(例如,当数据结构发生更改或某些字段变为可空等时按需执行)?
    • 很遗憾,这还不可能。我们确实知道它在某些情况下会很有用,但它还没有进入我们的待办事项列表的顶部。但是您可以打开一张票,详细说明该功能以及您对 API 的想象:hibernate.atlassian.net/projects/HSEARCH
    • 更新:手动触发的架构更新将在 Hibernate Search 6.0.0.Beta6 中可用,因为我们解决了这个问题:hibernate.atlassian.net/browse/HSEARCH-3759
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-17
    • 2011-11-17
    • 2021-07-28
    • 1970-01-01
    相关资源
    最近更新 更多