Hibernate Search:获取SQL IN运算符的功能

时间:2019-01-28 10:53:32

标签: java hibernate hibernate-search

在Hibernate搜索中创建查询时能否获得SQL IN运算符的功能?

例如,我有以下两个简单的类(省略了构造函数,getter和setter):

@Entity
@Indexed
public class Product {
    private long id;
    @Field
    private String title;
    @IndexedEmbedded
    private Category category;
}

@Entity
public class Category {
    private long id;
    @Field
    private String name;
}

目前,我有以下查询,该查询按标题搜索产品:

org.apache.lucene.search.Query luceneQuery = queryBuilder
        .keyword()
        .onField("title")
        .matching(queryString)
        .createQuery();

但是我只想按标题在特定类别中搜索产品。有要搜索的类别ID(或名称)列表,如何创建此类查询?

我找到了this SO question,但是作者没有找到合适的解决方案。也许现在这样的功能已经存在?

感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

首先,索引类别的ID:

@Entity
@Indexed
public class Product {
    private long id;
    @Field
    private String title;
    @IndexedEmbedded
    private Category category;
}

@Entity
public class Category {
    @Field // Added this
    private long id;
    @Field
    private String name;
}

然后,确保使用例如mass indexer重新索引数据。

然后,按照以下说明更改查询代码。

您首先需要“ SQL IN”,它在Lucene世界中表示为category.id = <first> OR category.id = <second> OR ...。只有布尔运算符与您可能习惯的(see here)有点不同;在您的情况下,您希望“至少一个”子句匹配,因此您必须使用should运算符:

List<Long> categoryIds = ...; // Provided by the user
BooleanJunction<?> categoryIdJunction = queryBuilder.bool();
for ( categoryId : categoryIds ) {
    categoryIdJunction.should(
        queryBuilder
            .keyword()
            .onField("category.id")
            .matching(categoryId)
            .createQuery();
    );
}
org.apache.lucene.search.Query categoryIdQuery = categoryIdJunction.createQuery();

最后,您需要将该查询与标题上的其他查询合并。为此,请使用另一个布尔连接,这次使用must运算符(所有子句必须匹配):

org.apache.lucene.search.Query titleQuery = queryBuilder
        .keyword()
        .onField("title")
        .matching(queryString)
        .createQuery();
org.apache.lucene.search.Query luceneQuery = queryBuilder.bool()
        .must( categoryIdQuery )
        .must( titleQuery )
        .createQuery();