Java 在Hibernate搜索中使用多个关键字进行索引搜索

Java 在Hibernate搜索中使用多个关键字进行索引搜索,java,lucene,hibernate-search,Java,Lucene,Hibernate Search,我的应用程序使用HibernateSearch4.5.0.Final,当我尝试只使用一个关键字进行搜索时,它运行良好。但是如果我尝试使用两个关键字,Hibernate搜索不使用第二个关键字,HS只考虑第一个关键字 例如,如果我尝试搜索James,搜索工作正常,应用程序返回索引中的所有James。但是如果我尝试搜索James Hetfield,结果同样都是James,而不是名为James Hetfield的唯一结果。我需要像对待詹姆斯和海特菲尔德一样对待詹姆斯和海特菲尔德 编辑:我犯了一个错误。搜

我的应用程序使用HibernateSearch4.5.0.Final,当我尝试只使用一个关键字进行搜索时,它运行良好。但是如果我尝试使用两个关键字,Hibernate搜索不使用第二个关键字,HS只考虑第一个关键字

例如,如果我尝试搜索James,搜索工作正常,应用程序返回索引中的所有James。但是如果我尝试搜索James Hetfield,结果同样都是James,而不是名为James Hetfield的唯一结果。我需要像对待詹姆斯和海特菲尔德一样对待詹姆斯和海特菲尔德

编辑:我犯了一个错误。搜索使用两个关键字,但使用与否和

我的代码:


找到了解决办法。我已拆分字符串并使用BooleanQuery。幸亏这是我的密码:

拆分:

String[] arrKeywords = keywords.split(" ");
this.search(Arrays.asList(arrKeywords));
然后,搜索:

public List<Person> search(String keywordsList) throws DAOException {
    try {
        FullTextEntityManager fullTextEm = Search.getFullTextEntityManager(this.entityManager);
        QueryBuilder qb = fullTextEm.getSearchFactory().buildQueryBuilder().forEntity(Person.class).get();

        List<Query> queryList = new LinkedList<Query>();
        Query query = null;

        for (String keyword : keywordsList) {
            query = qb.keyword().onFields("name", "email", "username", "phone").matching(keyword).createQuery();
            queryList.add(query);
        }

        BooleanQuery finalQuery = new BooleanQuery();
        for (Query q : queryList) {
            finalQuery.add(q, Occur.MUST);
        }

        FullTextQuery fullTextQuery = fullTextEm.createFullTextQuery(query);
        fullTextQuery.setProjection("name", "email", "username", "phone");
        Sort sortField = new Sort(new SortField("name_order", SortField.STRING));
        fullTextQuery.setSort(sortField);
        return fullTextQuery.getResultList();
    }
    catch (Exception e) {
        logger.error("Error searching index: " + keywords, e);
        throw new DAOException(e);
    }
}

找到了解决办法。我已拆分字符串并使用BooleanQuery。幸亏这是我的密码:

拆分:

String[] arrKeywords = keywords.split(" ");
this.search(Arrays.asList(arrKeywords));
然后,搜索:

public List<Person> search(String keywordsList) throws DAOException {
    try {
        FullTextEntityManager fullTextEm = Search.getFullTextEntityManager(this.entityManager);
        QueryBuilder qb = fullTextEm.getSearchFactory().buildQueryBuilder().forEntity(Person.class).get();

        List<Query> queryList = new LinkedList<Query>();
        Query query = null;

        for (String keyword : keywordsList) {
            query = qb.keyword().onFields("name", "email", "username", "phone").matching(keyword).createQuery();
            queryList.add(query);
        }

        BooleanQuery finalQuery = new BooleanQuery();
        for (Query q : queryList) {
            finalQuery.add(q, Occur.MUST);
        }

        FullTextQuery fullTextQuery = fullTextEm.createFullTextQuery(query);
        fullTextQuery.setProjection("name", "email", "username", "phone");
        Sort sortField = new Sort(new SortField("name_order", SortField.STRING));
        fullTextQuery.setSort(sortField);
        return fullTextQuery.getResultList();
    }
    catch (Exception e) {
        logger.error("Error searching index: " + keywords, e);
        throw new DAOException(e);
    }
}

在查询生成过程中使用关键字MUST。Hibernate Search还支持使用各种策略组合查询:

-应:查询应包含子查询的匹配元素

-必须:查询必须包含子查询的匹配元素

-不能:查询不能包含子查询的匹配元素

聚合类似于布尔值的AND、OR和NOT

    Query combinedQuery = queryBuilder
   .bool()

   .must(queryBuilder.phrase()
   .onField("productName).sentence("samsung galaxy s8")
   .createQuery())

   .must(queryBuilder.keyword()
   .onField("productCategory").matching("smartphone")
   .createQuery())

   .createQuery();


    // wrap Lucene query in an Hibernate Query object
    org.hibernate.search.jpa.FullTextQuery jpaQuery =
    fullTextEntityManager.createFullTextQuery(combinedQuery, Product.class);

    // execute search and return results (sorted by relevance as default)
    @SuppressWarnings("unchecked")
    List<Product> results = jpaQuery.getResultList();

此参考从链接中获取,在查询构建过程中使用关键字MUST。Hibernate Search还支持使用各种策略组合查询:

-应:查询应包含子查询的匹配元素

-必须:查询必须包含子查询的匹配元素

-不能:查询不能包含子查询的匹配元素

聚合类似于布尔值的AND、OR和NOT

    Query combinedQuery = queryBuilder
   .bool()

   .must(queryBuilder.phrase()
   .onField("productName).sentence("samsung galaxy s8")
   .createQuery())

   .must(queryBuilder.keyword()
   .onField("productCategory").matching("smartphone")
   .createQuery())

   .createQuery();


    // wrap Lucene query in an Hibernate Query object
    org.hibernate.search.jpa.FullTextQuery jpaQuery =
    fullTextEntityManager.createFullTextQuery(combinedQuery, Product.class);

    // execute search and return results (sorted by relevance as default)
    @SuppressWarnings("unchecked")
    List<Product> results = jpaQuery.getResultList();

此参考从链接中获取

您使用的分析仪是什么?在匹配之前是否可以尝试调用ignoreAnalyzer?另一个选项可能是拆分字符串并使用BooleanJunction和调用junction.mustsubquery对每个单词发出查询。我想我没有使用任何分析器,因为我没有指定任何分析器。如果有,我可能正在使用默认值。我试着打电话给.ignoreAnalyzer,但现在它找不到任何东西,即使只有一个关键字。我编辑了我的问题。搜索使用两个关键字,但使用的是与否和。谢谢@thomas。我做了一些更改,但我遵循了您关于布尔连接的提示。您使用的是什么分析器?在匹配之前是否可以尝试调用ignoreAnalyzer?另一个选项可能是拆分字符串并使用BooleanJunction和调用junction.mustsubquery对每个单词发出查询。我想我没有使用任何分析器,因为我没有指定任何分析器。如果有,我可能正在使用默认值。我试着打电话给.ignoreAnalyzer,但现在它找不到任何东西,即使只有一个关键字。我编辑了我的问题。搜索使用两个关键字,但使用的是与否和。谢谢@thomas。我做了一些改变,但我遵循了你关于布尔连接的提示。