如何在 Hibernate search 6 中获取结果集的亮点?

问题描述 投票:0回答:1

我在我的 java 应用程序中使用 Hibernate search 6 Lucne 后端。

我正在执行各种搜索操作,包括模糊搜索。

我获得搜索结果,没有任何问题。

现在我想展示在结果列表中选择每个结果的原因是什么。

假设搜索关键字是“test”,在“name”、“description”、“Id”等字段中进行模糊搜索。我在列表中得到了 10 个结果。现在我想突出显示每个结果的字段中的值,这些值导致该结果成为匹配结果。

eg:将以下内容视为搜索结果 List 对象中的项目之一。 (为了清楚起见,我将其编写为 JSON 格式)

 {  
    name:"ABC some test name",
    description: "this is a test element",
    id: "abc123"
}

结果表明它被选为搜索结果,因为关键字“test”同时出现在“名称”和“描述”字段中。当我显示搜索结果时,我想在前端突出显示这些特定字段。

目前,我正在通过 java REST API 将搜索结果检索到我的 Angular 前端。如何在我的 java 应用程序中使用 Hibernate search 6 获取这些特定字段及其值?

到目前为止,我已经浏览了 Hibernate search 6 文档,但一无所获。 (https://docs.jboss.org/hibernate/stable/search/reference/en-US/html_single/#preface)过去一周还查看了网络上似乎相关的问题,但没有得到任何结果远的。看来我的要求有点具体,这就是为什么我需要你的帮助。

java hibernate fuzzy-search hibernate-search-6
1个回答
1
投票

Hibernate Search 中尚未实现突出显示,请参阅 HSEARCH-2192 => 从 Hibernate Search 6.2 开始,它已实现!请参阅https://hibernate.org/search/releases/6.2/#search-highlightinghttps://docs.jboss.org/hibernate/stable/search/reference/en-US/html_single/#search- dsl-突出显示


旧答案:

话虽这么说,您可以利用本机 Elasticsearch / Lucene API。

使用 Elasticsearch 相对简单:您可以使用 请求转换器

highlight
元素添加到 HTTP 请求,然后使用
jsonHit
投影
检索每个命中的 JSON,其中包含
 highlight
元素,包括突出显示的字段和突出显示的片段。

使用 Lucene 会更复杂,并且您必须依赖不受支持的功能,但这是可行的。

从 Hibernate Search 谓词中检索 Lucene

Query

SearchPredicate predicate = ...;
Query query = LuceneMigrationUtils.toLuceneQuery(predicate);

然后进行突出显示:Hibernate 搜索突出显示未分析的字段 可能会有所帮助,因此该代码使用旧版本的 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 Search 元数据: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/参考/en-US/html_single/#search-dsl-query-explain

© www.soinside.com 2019 - 2024. All rights reserved.