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

Hibernate Search: Getting the functionality of the SQL IN operator

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

比如我有这两个简单的类(省略了构造函数,getters和setters):

@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,但是作者没有找到合适的解决方案。也许现在这样的功能已经存在了?

如有任何帮助,我将不胜感激。

首先,索引类别的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);在您的情况下,您希望 "at least one" 子句匹配,因此您必须使用 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();