在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,但是作者没有找到合适的解决方案。也许现在这样的功能已经存在?
感谢您的帮助。
答案 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();