我使用hibernate搜索(最新版本)与本地Lucene后端。我有两个实体如下:
@Entity
@Indexed
public class A {
@Id
private Long id;
@FullTextField
private String text;
@KeywordField
private String keyword;
}
@Entity
public class B {
private BigDecimal number;
@OneToOne
@JoinColumn(name = "a_id")
private A a;
}
我有一个质量索引器,在应用程序启动时处理索引A实体。在搜索时,我希望搜索结果按实体b的数字字段排序。
我的搜索函数是一个简单的布尔谓词,如下
.where(f -> f.bool()
.should(f.match().field("text").matching(query))
.should(f.match().field("keyword").matching(query.toUpperCase(Locale.ENGLISH)))
)
.fetch(offset, limit)
我应该怎么做,以订购/提高搜索结果取决于另一个实体的另一个字段,其中有一对一的关系?
你用了" boost "这个词,但我认为你只是在说"排序"。"bootsting"是一个不同的概念,影响得分,只间接影响命中的顺序。
要按number
属性排序,必须将其嵌入到为A
创建的索引文档中。为此,使用@IndexedEmbedded
:
@Entity
@Indexed
public class A {
@Id
private Long id;
@FullTextField
private String text;
@KeywordField
private String keyword;
// Add this, and make sure to update it every time you update B.a
@OneToOne(mappedBy = "a")
@IndexedEmbedded
private B b;
}
@Entity
public class B {
private BigDecimal number;
@OneToOne
@JoinColumn(name = "a_id")
private A a;
}
警告:确保每次调用b.setA(...)
时,也调用a.setB(...)
,以便所有实体保持一致。否则,Hibernate Search将无法正确索引您的数据。
然后注释number
,使其被索引和排序:
@Entity
public class B {
@GenericField(searchable = Searchable.NO, sortable = Sortable.YES)
private BigDecimal number;
@OneToOne
@JoinColumn(name = "a_id")
private A a;
}
然后在查询中添加一个排序:
.where(f -> f.bool()
.should(f.match().field("text").matching(query))
.should(f.match().field("keyword").matching(query.toUpperCase(Locale.ENGLISH)))
)
.sort(f -> f.field("b.number").asc())
.fetch(offset, limit)