elasticsearch,hibernate-search,Java,Hibernate,elasticsearch,Hibernate Search" /> elasticsearch,hibernate-search,Java,Hibernate,elasticsearch,Hibernate Search" />

Java 如何在HibernateSearch中突出显示Elasticsearch

Java 如何在HibernateSearch中突出显示Elasticsearch,java,hibernate,elasticsearch,hibernate-search,Java,Hibernate,elasticsearch,Hibernate Search,背景:我们正在将java应用程序从Lucene转换为Elasticsearch 5.6.6。使用Hibernate 5.2.11和Hibernate Search 5.8.2。我们有许多自定义分析器,它们在ES中注册(根据使用ElasticsearchAnalysisDefinitionProvider),并将它们作为插件导入ES服务器 对于基本查询,使用查询DSL似乎相当简单,但是有一段突出显示的代码我一直无法使用 与直接处理Lucene相比,ES中的分析器被移除了一些,这可能是我的主要问题之

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

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

与直接处理Lucene相比,ES中的分析器被移除了一些,这可能是我的主要问题之一

这是我们需要转换/工作的现有方法;当前在调用以下命令的第三行中得到一个NullPointerException:
…getAnalyzer(analyzerName)
,当它执行
SearchIntegration integration=integrations.get(LuceneEmbeddedIndexManagerType.INSTANCE)

是否有其他方法获取分析仪或此处出现错误?
但更重要的是,在使用Hibernate搜索时,如何突出显示片段

是否有其他方法获取分析仪或此处出现错误

如果为Elasticsearch定义了Analyzer,则无法获取
org.apache.lucene.analysis.Analyzer的实例,因为在这种情况下,Analyzer仅位于远程Elasticsearch集群上,Hibernate搜索从不直接使用分析器:它只将分析器定义推送到Elasticsearch,然后使用对该分析器的引用(名称)

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

但更重要的是,在使用Hibernate搜索时,如何突出显示片段

Hibernate搜索本身不提供突出显示功能;只有传统上支持Hibernate搜索的技术Lucene能够做到这一点。当您使用Elasticsearch集成时,您将Lucene技术替换为Elasticsearch技术(或多或少)。因此,你必须以不同的方式做事

HibernateSearch6.x Hibernate Search 6.0.0。Beta3+提供了一个新的API,允许您更轻松地利用高级Elasticsearch功能。如果您希望突出显示作为搜索查询的一部分,那么就不再需要直接依赖REST客户端

您可以使用a向HTTP请求添加a,然后使用检索每个命中的JSON,其中包含一个
highlight
元素,该元素包括突出显示的字段和突出显示的片段

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

一个选择是继续使用Lucene。为了做到这一点,您必须定义完全相同的分析器,但是对于Lucene。您可以使用与Elasticsearch几乎相同的方法。 然后您应该能够调用
getAnalyzer()
来检索Lucene分析器并使用Lucene API执行高亮显示

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

另一个选项是向Elasticsearch发送
高亮显示
查询。但是,这需要访问低级API才能发送JSON查询,我甚至不确定您是否可以使用ES API对任意文本段(仅对索引文档)执行高亮显示。如果要调查,请提供一些有用的信息:

  • 你必须
  • 你必须使用
  • Elasticsearch 5.6中的允许在执行搜索查询时突出显示结果
  • in-Elasticsearch 5.6允许对任意字符串运行分析,但似乎不提供突出显示

好的,我添加了一个Lucene分析定义提供程序(除了现有的ES分析定义提供程序之外),并添加了
hibernate.search.Lucene.analysis\u definition\u提供程序的映射
,但没有调用它。有什么想法吗?查看正在使用的所有相关hibernate.search属性映射是否会有所帮助?对,对此表示抱歉。我更新了我的答案:如果你只使用Elasticsearch集成,Hibernate搜索默认会忽略Lucene分析器。强制Hibernate搜索考虑Lucene配置的唯一方法是在一个实体上放置
@AnalyzerDef
注释,而不是在任何地方使用它。我知道这很奇怪,但这是传统行为。太棒了!我在我们的一个实体上添加了
@AnalyzerDef(name=“dummyCustomAnalyzer”,tokenizer=@TokenizerDef(factory=KeywordTokenizerFactory.class))
,正如您所说,新添加的自定义LuceneAnalysisDefinitionProvider在下一次启动时被调用。现有的highlighter代码现在可以正常工作了。我认为最好还是将所有其他查询转换为新的HibernateSearch查询DSL,这就是我遇到这段更亮的代码时正在做的事情?很高兴它有所帮助。是的,如果您想使用Elasticsearch集成,最好使用查询DSL。当您构建查询时,查询DSL会带来一些模式验证,这总是很好的。在Hibernate搜索的下一个主要版本中,当Elasticsearch支持不再是实验性的时,DSL将有所不同,但它将是t
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);
    }
}