【问题标题】:How to search two and more terms in Hibernate Search?如何在 Hibernate Search 中搜索两个或更多术语?
【发布时间】:2023-03-20 00:06:01
【问题描述】:

我想使用 Hibernate Search 进行正确的查询,其中包含以下参数:

1) 将短语分解为单词并在多个字段中搜索每个单词;

2) 搜索部分单词的能力;

3) 忽略大小写

在我的代码中,我使用术语迭代来实现它。但我想充分利用 Hibernate Search。

@Repository
public class ProductSearch {
    @PersistenceContext
    EntityManager em;

    public List<Product> searchProducts(String text) throws InterruptedException, ParseException {


        List<Product> allResults = new ArrayList<>();
        for (String word : text.toLowerCase().split(" ")) {
            Query wildcardQuery = getQueryBuilder()
                    .keyword()
                    .wildcard()
                    .onFields("productNumber", "category.uaName")
                    .matching("*" + word + "**")
                    .createQuery();

            List<Product> results = getJpaQuery(wildcardQuery).getResultList();
            for (Product result : results) {
                if(!allResults.contains(result)) {
                    allResults.add(result);
                }
            }
        }

        return allResults;
    }

    private FullTextQuery getJpaQuery(org.apache.lucene.search.Query luceneQuery) {

        FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(em);

        return fullTextEntityManager.createFullTextQuery(luceneQuery, Product.class);
    }

    private QueryBuilder getQueryBuilder() throws InterruptedException {

        FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(em);
        fullTextEntityManager.createIndexer().startAndWait();

        return fullTextEntityManager.getSearchFactory()
                .buildQueryBuilder()
                .forEntity(Product.class)
                .get();
    }
}

谁能帮助我,因为我是 Hibernate Search 的新手?

也许有人可以分享他们自己的代码?我将不胜感激

我已经解决了我的问题,但有两个版本的代码:

版本 1:


    public List<Product> searchProducts(String text) throws InterruptedException, ParseException {
String[] fields = {"productNumber", "category.uaName"};
        FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(em);
        fullTextEntityManager.createIndexer().startAndWait();
        org.apache.lucene.queryparser.classic.MultiFieldQueryParser parser = new MultiFieldQueryParser(
                fields,

                fullTextEntityManager.getSearchFactory().getAnalyzer("customanalyzer_query")
        );
        org.apache.lucene.search.Query luceneQuery =
                parser.parse( text);
        org.hibernate.search.jpa.FullTextQuery fullTextQuery =
                fullTextEntityManager.createFullTextQuery( luceneQuery, Product.class );
        List result = fullTextQuery.getResultList();
return result;
    }

版本 2:

    public List<Product> searchProducts(String text) throws InterruptedException, ParseException {

        Query query = getQueryBuilder()
                .keyword()
                .onFields("productNumber", "category.uaName")
                .matching(text)
                .createQuery();

        List<Product> results = getJpaQuery(query).getResultList();

        return results;
    }

    private FullTextQuery getJpaQuery(org.apache.lucene.search.Query luceneQuery) {

        FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(em);

        return fullTextEntityManager.createFullTextQuery(luceneQuery, Product.class);
    }

    private QueryBuilder getQueryBuilder() throws InterruptedException {

        FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(em);
        fullTextEntityManager.createIndexer().startAndWait();

        return fullTextEntityManager.getSearchFactory()
                .buildQueryBuilder()
                .forEntity(Product.class)
                .overridesForField("productNumber", "customanalyzer_query")
                .overridesForField("category.uaName", "customanalyzer_query")
                .get();

    }

【问题讨论】:

    标签: hibernate jpa lucene full-text-search hibernate-search


    【解决方案1】:

    正如here 已经回答的那样,最简单的解决方案就是不使用通配符查询。

    只需使用带有 edge-ngram 过滤器的适当分析器,从查询字符串中删除通配符,然后删除代码中的 .wildcard()。 有关分析的更多信息,请参阅this answer

    【讨论】:

    • 非常感谢您的回答以及有关此主题的许多有用的文章。我有两个版本的代码可以解决我的问题。您认为哪个版本更合理、更实用?请见上文。我已经编辑了我的问题
    • 我个人会使用#2,因为第一个解决方案将解析查询,即它将允许用户控制诸如模糊性、通配符、执行短语查询等,这需要特殊的语法可能会被错误地使用,并且会使您的用户感到困惑。
    猜你喜欢
    • 2012-12-03
    • 2011-03-12
    • 2018-10-01
    • 1970-01-01
    • 2021-02-02
    • 1970-01-01
    • 1970-01-01
    • 2015-08-02
    • 1970-01-01
    相关资源
    最近更新 更多