【问题标题】:How can I get the highlights of my result set in Hibernate search 6?如何在 Hibernate Search 6 中获得我的结果集中的亮点?
【发布时间】:2023-02-02 00:14:30
【问题描述】:

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

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

我得到的搜索结果没有任何问题。

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

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

例如:将以下内容视为搜索结果列表对象中的一项。 (为清楚起见,我用 JSON 格式编写了它)

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

结果表明它已被选为搜索结果,因为关键字“test”同时存在于“name”和“description”字段中。当我显示搜索结果时,我想在前端突出显示这些特定字段。

目前,我正在通过 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】:

    Hibernate Search 中尚未实现突出显示,请参阅HSEARCH-2192

    也就是说,您可以利用原生 Elasticsearch / Lucene API。

    使用 Elasticsearch 相对容易:您可以使用 request transformerhighlight 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

    【讨论】:

    • 嗨,@yrodiere 非常感谢您的指导。我会试试这个并在这里分享我的经验。
    猜你喜欢
    • 1970-01-01
    • 2010-10-29
    • 2020-03-07
    • 1970-01-01
    • 1970-01-01
    • 2014-08-02
    • 1970-01-01
    • 2021-10-03
    • 1970-01-01
    相关资源
    最近更新 更多