首页 > 解决方案 > 如何在 Hibernate Search 中搜索两个或更多术语?

问题描述

我想使用 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();

    }

标签: hibernatejpalucenefull-text-searchhibernate-search

解决方案


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

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


推荐阅读