首页 > 解决方案 > 如何通过 Elasticsearch 在 HibernateSearch 中进行突出显示

问题描述

背景:我们正在将我们的 java 应用程序从 Lucene 转换为 Elasticsearch 5.6.6。使用 Hibernate 5.2.11 和 Hibernate-Search 5.8.2。我们有许多在 ES 中注册的自定义分析器(根据文档使用 ElasticsearchAnalysisDefinitionProvider ),并将它们作为插件导入到 ES 服务器中。

对于基本查询,使用 Query DSL 似乎相当简单,但是有一段突出显示的代码我一直无法工作。

ES 中的分析器比直接处理 Lucene 时要删除一些,这可能是我的主要问题之一。

这是我们需要转换/工作的现有方法;目前在调用的第 3 行中收到 NullPointerException ...getAnalyzer(analyzerName),我将其跟踪到 ImmutableSearchFactory::getAnalyzerSearchIntegration integration = integrations.get( LuceneEmbeddedIndexManagerType.INSTANCE )

private boolean isMatch(String field, String target, String analyzerName, Query sourceQ, FullTextSession fts) {

    Analyzer analyzer = fts.getSearchFactory().getAnalyzer(analyzerName);

    Highlighter highlighter = new Highlighter(new QueryScorer(sourceQ, field));
    highlighter.setTextFragmenter(new NullFragmenter());

    try {
        String result = highlighter.getBestFragment(analyzer, field, target);
        return StringUtils.hasText(result);
    }
    catch (IOException e) {
        throw new IllegalStateException("Caught IOException while highlighting a String?..", e);
    }
    catch (InvalidTokenOffsetsException e) {
        throw new IllegalStateException("Caught InvalidTokenOffsetsException while highlighting a String?..", e);
    }
}

有没有其他方法可以让分析仪或这里有什么不正确的地方?
但更重要的是,在使用 Hibernate Search over ES 时如何突出显示片段?

标签: javahibernateelasticsearchhibernate-search

解决方案


有没有其他方法可以让分析仪或这里有什么不正确的地方?

如果您为 Elasticsearch 定义了分析器,则无法获得实例org.apache.lucene.analysis.Analyzer,因为在这种情况下,分析器仅存在于远程 Elasticsearch 集群上,而 Hibernate Search 从不​​直接使用分析器:它只会将分析器定义推送到 Elasticsearch,然后使用引用到那个分析器(名字)。

您要做的是使用仅存在于另一台服务器(ES 服务器)中的分析器使用 Lucene 在本地运行分析。这行不通。

但更重要的是,在使用 Hibernate Search over ES 时如何突出显示片段?

Hibernate Search 本身不提供高亮功能;只有传统上运行在 Hibernate Search 之后的技术 Lucene 可以做到。当您使用 Elasticsearch 集成时,您正在将 Lucene 技术替换为 Elasticsearch 技术(或多或少)。因此,您必须以不同的方式做事。

休眠搜索 6.x

Hibernate Search 6.0.0.Beta3+ 提供了一个新的 API,允许您更轻松地利用高级 Elasticsearch 功能。如果您想在搜索查询中突出显示,则无需再直接依赖 REST 客户端。

您可以使用请求转换器将highlight元素添加到 HTTP 请求,然后使用jsonHit投影来检索每个命中的 JSON,其中包含一个highlight包含突出显示字段和突出显示片段的元素。

休眠搜索 5.x

在 Hibernate Search 5.x 中,您无法访问搜索请求和响应的原始 JSON,因此需要另一种方法。

一种选择是让您继续使用 Lucene。为此,您必须为 Lucene 定义完全相同的分析器。您可以像使用 Elasticsearch 一样使用分析定义提供程序。然后您应该能够调用getAnalyzer()以检索 Lucene 分析器并使用 Lucene API 执行突出显示。

但是有一个警告:如果您只使用 Elasticsearch 集成,Hibernate Search 默认会忽略 Lucene 分析器。强制 Hibernate Search 将 Lucene 配置考虑在内的唯一方法是@AnalyzerDef在您的一个实体上添加注释,而不是在任何地方使用它。如果添加注释不是一个选项,您也可以使用编程映射来定义它。我知道这很奇怪,但这是遗留行为。

highlight另一种选择是让您向 Elasticsearch发送查询。但是,这将需要访问低级 API 以发送 JSON 查询,而且我什至不确定您是否可以使用 ES API 对任意一段文本(仅在索引文档上)执行突出显示。如果您想调查一些有用的信息:


推荐阅读