Java Hibernate搜索中的布尔查询

Java Hibernate搜索中的布尔查询,java,hibernate,jakarta-ee,lucene,hibernate-search,Java,Hibernate,Jakarta Ee,Lucene,Hibernate Search,我试图理解Hibernate搜索中的一般查询。我在理解forEntity(…)方法时遇到一些困难。这就是文件中所说的: 让我们看看如何使用API。首先需要创建附加到给定索引实体类型的查询生成器。这个QueryBuilder将知道使用什么分析器以及应用什么字段桥接器。您可以创建几个QueryBuilder(查询根中涉及的每个实体类型对应一个)。您可以从SearchFactory获得QueryBuilder 从第节: 从上面你可以看到你必须命名一个实体。当您想要创建自己的querybuilder以在

我试图理解Hibernate搜索中的一般查询。我在理解
forEntity(…)
方法时遇到一些困难。这就是文件中所说的:

让我们看看如何使用API。首先需要创建附加到给定索引实体类型的查询生成器。这个QueryBuilder将知道使用什么分析器以及应用什么字段桥接器。您可以创建几个QueryBuilder(查询根中涉及的每个实体类型对应一个)。您可以从SearchFactory获得QueryBuilder

从第节:

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


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

如果您希望能够从一个查询返回多个实体,可以如您所述使用
QueryBuilder
,但您需要在
createFullTextQuery
调用中指定多个实体。例如,如果您有一个
书籍
实体和一个
电影
实体,并且希望查找标题以
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
实体创建,但是
Book
s和
Movie
s都是在
createFullTextQuery
调用中指定的。

布尔运算符的调用应该不是或是因为它们在Lucene API和文档中的名称,因为它更合适:它不仅影响布尔决策,还影响结果的评分

例如,如果您搜索“菲亚特品牌”或“蓝色”的汽车,则菲亚特和蓝色品牌的汽车也将被返回,并且其得分高于蓝色但非菲亚特品牌的汽车

它可能会觉得很麻烦,因为它是编程的,并且提供了许多详细的选项。一个更简单的替代方法是对查询使用一个简单的字符串,并使用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();
Collection namesCollection=getNames();//例如,包含“比利”和“鲍勃”
StringBuilder名称=新StringBuilder(100);
for(字符串名称:namesCollection){
names.append(name.append(“”;//不要在意结果字符串末尾的空格。
}
QueryBuilder b=fts.getSearchFactory().buildQueryBuilder().forEntity(Person.class.get();
Query luceneQuery=b.bool()
.应该(
//在同一字段中搜索多个可能的值
b、 关键字().onField(“firstName”).matching(sb.toString()).createQuery()
)
.must(b.keyword().onField(“lastName”).matching(“thornton”).createQuery())
.createQuery();

但是
forEntity
然后做什么呢?如果没有什么区别,为什么要放在那里?它必须有一个目的?
forEntity
用于确定要使用的分析器/字段桥接器,并验证字段名称。看起来有人打算在
QueryContextBuilder
中添加一个
forenties
方法(界面中有一个
TODO
),但它还没有实现(从4.5.0开始)。那么这个答案是不是错了?电影并没有和书一样的场桥和分析器,所以它会失败吗?或者这是我不明白的东西?我用
Book
有自定义分析器定义和
Movie
没有该定义成功地测试了这一点。我应该补充一点,您也可以完全避免
QueryBuilder
,方法是使用Lucene API直接创建
查询
对象,然后将查询对象传递给
createFullTextQuery
,其中包含您希望搜索/返回的类。我不是专家,但根据5.1.2.1(本章末尾的第三个示例)。关键词查询在Hibernate搜索文档中,您应该能够像这样构建查询:因此,有(名字最好是“billy”或“bob”)和(lastName=“thornton”)的人,尽管我认为这不会给优秀的老billy bob thornton更高的分数;-)。我不确定这是否回答了我的问题。教室里的同学在干什么?为什么有它?
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();