如何通过 Elasticsearch 在 HibernateSearch 中突出显示
How to do highlighting within HibernateSearch over Elasticsearch
背景:我们正在将 java 应用程序从 Lucene 转换为 Elasticsearch 5.6.6。使用 Hibernate 5.2.11 和 Hibernate-Search 5.8.2。我们有许多自定义分析器,它们在 ES 中注册(根据 documentation 使用 ElasticsearchAnalysisDefinitionProvider),并将它们作为插件导入到 ES 服务器中。
对于基本查询,使用查询 DSL 似乎相当简单,但是有一段突出显示的代码我无法开始工作。
与直接处理 Lucene 相比,ES 中的分析器被移除了一些,这可能是我的主要问题之一。
这是我们需要获取的现有方法converted/working;当前在第 3 行中收到 NullPointerException 调用:...getAnalyzer(analyzerName)
,当它执行 SearchIntegration integration = integrations.get( LuceneEmbeddedIndexManagerType.INSTANCE )
时,我将其跟踪到 ImmutableSearchFactory::getAnalyzer
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);
}
}
是否有其他获取分析器的方法或此处不正确的地方?
但更重要的是,在 ES 上使用 Hibernate Search 时如何突出显示片段?
Is there another way to get the analyzer or something incorrect here?
如果您为 Elasticsearch 定义了分析器,则无法获取 org.apache.lucene.analysis.Analyzer
的实例,因为在这种情况下,分析器仅存在于远程 Elasticsearch 集群上,而 Hibernate Search 从不直接使用分析器:它仅将分析器定义推送到 Elasticsearch,然后使用对该分析器(名称)的引用。
您要做的是使用仅存在于另一台服务器(ES 服务器)中的分析器来使用 Lucene 运行 在本地进行分析。这行不通。
But more importantly, how do you highlight a fragment when using Hibernate Search over ES?
Hibernate Search 本身不提供突出显示功能;只有 Lucene,运行 传统上落后于 Hibernate Search 的技术可以做到。当您使用 Elasticsearch 集成时,您正在将 Lucene 技术换成 Elasticsearch 技术(或多或少)。因此你必须以不同的方式做事。
休眠搜索 6.x
Hibernate Search 6.0.0.Beta3+ 提供了一个新的 API,让您可以更轻松地利用高级 Elasticsearch 功能。如果您想突出显示作为搜索查询的一部分,则无需再直接依赖 REST 客户端。
您可以使用 request transformer to add a highlight
element to the HTTP request, then use the jsonHit
projection 检索每个命中的 JSON,其中包含一个包含突出显示字段和突出显示片段的 highlight
元素。
休眠搜索 5.x
在 Hibernate Search 5.x 中,您无法访问搜索请求和响应的原始 JSON,因此需要另一种方法。
您可以选择继续使用 Lucene。为此,您必须定义完全相同的分析器,但要针对 Lucene。您可以使用与 Elasticsearch 几乎相同的方式使用 analysis definition provider。
然后你应该能够调用 getAnalyzer()
来检索 Lucene 分析器并使用 Lucene APIs.
执行突出显示
但有一个警告:如果您只使用 Elasticsearch 集成,Hibernate Search 默认会忽略 Lucene 分析器。强制 Hibernate Search 考虑 Lucene 配置的唯一方法是在您的一个实体上放置一个 @AnalyzerDef
注释,而不是在任何地方使用它。如果添加注释不是一个选项,您也可以使用编程映射来定义它。这很奇怪,我知道,但这是遗留行为。
另一种选择是向 Elasticsearch 发送 highlight
查询。但是,这将需要访问低级 APIs 以发送 JSON 查询,我什至不确定您是否可以使用 ES APIs 对任意对象执行突出显示一段文本(仅在索引文档中)。如果您想调查,一些有用的信息:
- 你将不得不retrieve the Elasticsearch client
- Here is the documentation for the REST client 你将不得不使用
- Elasticsearch 5.6 中的 highlighting API 允许在执行搜索查询时突出显示结果
- Elasticsearch 5.6 中的 analyzer API 允许对任意字符串进行 运行 分析,但似乎不提供突出显示。
背景:我们正在将 java 应用程序从 Lucene 转换为 Elasticsearch 5.6.6。使用 Hibernate 5.2.11 和 Hibernate-Search 5.8.2。我们有许多自定义分析器,它们在 ES 中注册(根据 documentation 使用 ElasticsearchAnalysisDefinitionProvider),并将它们作为插件导入到 ES 服务器中。
对于基本查询,使用查询 DSL 似乎相当简单,但是有一段突出显示的代码我无法开始工作。
与直接处理 Lucene 相比,ES 中的分析器被移除了一些,这可能是我的主要问题之一。
这是我们需要获取的现有方法converted/working;当前在第 3 行中收到 NullPointerException 调用:...getAnalyzer(analyzerName)
,当它执行 SearchIntegration 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);
}
}
是否有其他获取分析器的方法或此处不正确的地方?
但更重要的是,在 ES 上使用 Hibernate Search 时如何突出显示片段?
Is there another way to get the analyzer or something incorrect here?
如果您为 Elasticsearch 定义了分析器,则无法获取 org.apache.lucene.analysis.Analyzer
的实例,因为在这种情况下,分析器仅存在于远程 Elasticsearch 集群上,而 Hibernate Search 从不直接使用分析器:它仅将分析器定义推送到 Elasticsearch,然后使用对该分析器(名称)的引用。
您要做的是使用仅存在于另一台服务器(ES 服务器)中的分析器来使用 Lucene 运行 在本地进行分析。这行不通。
But more importantly, how do you highlight a fragment when using Hibernate Search over ES?
Hibernate Search 本身不提供突出显示功能;只有 Lucene,运行 传统上落后于 Hibernate Search 的技术可以做到。当您使用 Elasticsearch 集成时,您正在将 Lucene 技术换成 Elasticsearch 技术(或多或少)。因此你必须以不同的方式做事。
休眠搜索 6.x
Hibernate Search 6.0.0.Beta3+ 提供了一个新的 API,让您可以更轻松地利用高级 Elasticsearch 功能。如果您想突出显示作为搜索查询的一部分,则无需再直接依赖 REST 客户端。
您可以使用 request transformer to add a highlight
element to the HTTP request, then use the jsonHit
projection 检索每个命中的 JSON,其中包含一个包含突出显示字段和突出显示片段的 highlight
元素。
休眠搜索 5.x
在 Hibernate Search 5.x 中,您无法访问搜索请求和响应的原始 JSON,因此需要另一种方法。
您可以选择继续使用 Lucene。为此,您必须定义完全相同的分析器,但要针对 Lucene。您可以使用与 Elasticsearch 几乎相同的方式使用 analysis definition provider。
然后你应该能够调用 getAnalyzer()
来检索 Lucene 分析器并使用 Lucene APIs.
但有一个警告:如果您只使用 Elasticsearch 集成,Hibernate Search 默认会忽略 Lucene 分析器。强制 Hibernate Search 考虑 Lucene 配置的唯一方法是在您的一个实体上放置一个 @AnalyzerDef
注释,而不是在任何地方使用它。如果添加注释不是一个选项,您也可以使用编程映射来定义它。这很奇怪,我知道,但这是遗留行为。
另一种选择是向 Elasticsearch 发送 highlight
查询。但是,这将需要访问低级 APIs 以发送 JSON 查询,我什至不确定您是否可以使用 ES APIs 对任意对象执行突出显示一段文本(仅在索引文档中)。如果您想调查,一些有用的信息:
- 你将不得不retrieve the Elasticsearch client
- Here is the documentation for the REST client 你将不得不使用
- Elasticsearch 5.6 中的 highlighting API 允许在执行搜索查询时突出显示结果
- Elasticsearch 5.6 中的 analyzer API 允许对任意字符串进行 运行 分析,但似乎不提供突出显示。