Hibernate Search中的布尔查询

时间:2014-08-25 14:31:53

标签: java hibernate java-ee lucene hibernate-search

我试图在Hibernate Search中理解一般的查询。我在理解forEntity(...)方法时遇到了一些麻烦。这就是文档所说的内容:

  

让我们看看如何使用API​​。首先需要创建附加到给定索引实体类型的查询构建器。此QueryBuilder将知道要使用的分析器和要应用的字段桥。您可以创建多个QueryBuilder(一个用于查询根目录中涉及的每个实体类型)。您从SearchFactory获得QueryBuilder。

来自:5.1.2. Building a Lucene query with the Hibernate Search query DSL

部分
QueryBuilder mythQB = searchFactory.buildQueryBuilder().forEntity( Myth.class ).get();

从上面你可以看到你必须命名一个实体。当您想要创建自己的查询构建器以在“根”查询中创建布尔查询时,您应该怎么做?你也应该绑定什么?

假设我想要一个应该匹配“Apples”或“Pie”的布尔查询。这是两个不同的实体,所以目前我有两个不同的查询构建器。但我需要第三个来创建一个布尔查询。它应该绑定到Object类吗?

2 个答案:

答案 0 :(得分:3)

如果您希望能够从单个查询中返回多个实体,则可以按照您的说明使用QueryBuilder,但是您希望在createFullTextQuery调用中指定多个实体。例如,如果您有Book实体和Movie实体,并且想要查找标题以d开头的所有书籍和电影,则可以使用以下查询:

QueryBuilder queryBuilder = fullTextSession.getSearchFactory().buildQueryBuilder().forEntity(Book.class).get();
Query query = queryBuilder.keyword().wildcard().onField("title").matching("d*").createQuery();
org.hibernate.Query fullTextQuery = fullTextSession.createFullTextQuery(query, Book.class, Movie.class);

请注意,查询构建器仅使用Book实体创建,但BookMovie都在createFullTextQuery调用中指定。

答案 1 :(得分:1)

由于Lucene API和文档中的名称,因此调用布尔运算符而不是OR,因为它更合适:它不仅影响布尔决策,而且还影响结果的评分。

例如,如果您搜索“菲亚特品牌”或“蓝色”的汽车,那么品牌菲亚特和蓝色的汽车也将被退回并且得分高于蓝色而不是菲亚特。

它可能感觉很麻烦,因为它是程序化的,并提供了许多详细的选项。更简单的替代方法是为查询使用简单的字符串,并使用QueryParser创建查询。通常,解析器对解析用户输入很有用,程序化的解析器更容易处理明确定义的字段;例如,如果你有你提到的集合,很容易在for循环中构建它。

Collection<String> namesCollection = getNames(); // Contains "billy" and "bob", for example
StringBuilder names = new StringBuilder(100);
for(String name : namesCollection) {
    names.append(name).append(" "); // Never mind the space at the end of the resulting string.
}

QueryBuilder b = fts.getSearchFactory().buildQueryBuilder().forEntity(Person.class).get();
Query luceneQuery = b.bool()
    .should(
        // Searches for multiple possible values in the same field
        b.keyword().onField("firstName").matching( sb.toString() ).createQuery()
    )
    .must(b.keyword().onField("lastName").matching("thornton").createQuery())
    .createQuery();