java - 如何通过 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 时如何突出显示片段?
解决方案
有没有其他方法可以让分析仪或这里有什么不正确的地方?
如果您为 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 对任意一段文本(仅在索引文档上)执行突出显示。如果您想调查一些有用的信息:
- 您必须检索 Elasticsearch 客户端
- 这是您必须使用的 REST 客户端的文档
- Elasticsearch 5.6 中的高亮 API允许在执行搜索查询时高亮显示结果
- Elasticsearch 5.6 中的分析器 API允许对任意字符串运行分析,但似乎不提供突出显示。
推荐阅读
- toit - 发布的消息是否可以通过 fetch 立即获得?
- flutter - PathMetric extractPath 的“结束”参数是什么
- azure-data-factory - 如何使用 Azure 查找活动获取文件中的行数
- youtube - YouTube Data API v3:按最受欢迎的视频排序
- c# - Linq 查询以包含已连接集合的项目数
- r - 以特定模式为 r 中数据名的奇数/偶数列命名
- c++ - 无法将数组中的浮点数转换为字符串
- c# - 以 asp dot net web 形式发布项目后访问排除的文件/文件夹
- java - 如何在记事本中放大和缩小 JtextArea
- regex - 如何将转义码转换为 html 或删除