Hibernate Search 中尚未实现突出显示,请参阅HSEARCH-2192。
也就是说,您可以利用原生 Elasticsearch / Lucene API。
使用 Elasticsearch 相对容易:您可以使用 request transformer 将 highlight element 添加到 HTTP 请求,然后使用 jsonHit projection 检索每个命中的 JSON,其中包含一个包含突出显示字段的 highlight 元素和突出显示的片段。
使用 Lucene 会更复杂,您将不得不依赖不受支持的功能,但这是可行的。
从 Hibernate Search 谓词中检索 Lucene Query:
SearchPredicate predicate = ...;
Query query = LuceneMigrationUtils.toLuceneQuery(predicate);
然后突出显示:Hibernate search highlighting not analyzed fields 可能会有所帮助,因此该代码使用旧版本的 Lucene,您可能需要对其进行调整:
String highlightText(Query query, Analyzer analyzer, String fieldName, String text) {
QueryScorer queryScorer = new QueryScorer(query);
SimpleHTMLFormatter formatter = new SimpleHTMLFormatter("<span>", "</span>");
Highlighter highlighter = new Highlighter(formatter, queryScorer);
return highlighter.getBestFragment(analyzer, fieldName, text);
}
您需要添加对org.apache.lucene:lucene-highlighter 的依赖。
要检索分析器,请使用 Hibernate 搜索元数据:https://docs.jboss.org/hibernate/stable/search/reference/en-US/html_single/#backend-lucene-access-analyzers
那么,连接点...类似的东西?
Highlighter createHighlighter(SearchPredicate predicate, SearchScope<?> scope) {
// Taking a shortcut here to retrieve the index manager,
// since we already have the scope
// WARNING: This only works when searching a single index
Analyzer analyzer = scope.includedTypes().iterator().next().indexManager()
.unwrap( LuceneIndexManager.class )
.searchAnalyzer();
// WARNING: this method is not supported and might disappear in future versions of HSearch
Query query = LuceneMigrationUtils.toLuceneQuery(predicate);
QueryScorer queryScorer = new QueryScorer(query);
SimpleHTMLFormatter formatter = new SimpleHTMLFormatter("<span>", "</span>");
return new Highlighter(formatter, queryScorer);
}
SearchSession searchSession = Search.session( entityManager );
SearchScope<Book> scope = searchSession.scope( Book.class );
SearchPredicate predicate = scope.predicate().match()
.fields( "title", "authors.name" )
.matching( "refactoring" )
.toPredicate();
Highlighter highlighter = createHighlighter(predicate, scope);
// Using Pair from Apache Commons, but others would work just as well
List<Pair<Book, String>> hits = searchSession.search( scope )
.select( select( f -> f.composite(
// Highlighting the title only, but you can do the same for other fields
book -> Pair.of( book, highlighter.getBestFragment(analyzer, "title", book.getTitle()))
f.entity()
) )
.where( predicate )
.fetch( 20 );
不确定是否可以编译,但这应该可以帮助您入门。
相关地,但不完全是你所要求的,有一个explain 功能可以了解为什么给定的命中具有给定的分数:https://docs.jboss.org/hibernate/stable/search/reference/en-US/html_single/#search-dsl-query-explain