Hibernate Search 是一个库,它通过自动索引实体,将 Hibernate ORM 与 Apache Lucene 或 Elasticsearch 集成,从而实现高级搜索功能:全文、地理空间、聚合等。有关更多信息,请参阅 hibernate.org 上的 Hibernate Search。

"订单,oo订单!" - 有时不仅国会议员需要被 点名,Hibernate Search 查询的结果也需要以特定的方式进行排序。

要这样做,只需在执行之前将一个 Sort 对象传递给全文查询,指定排序的字段。

FullTextSession session = ...;
QueryParser queryParser = ...;

FullTextQuery query = session.createFullTextQuery( queryParser.parse( "summary:lucene" ), Book.class );
Sort sort = new Sort( new SortField( "title", SortField.Type.STRING, false ) );
query.setSort( sort );
List<Book> result = query.list();

从 Lucene 5(Hibernate Search 5.5 所基于的版本)开始,如果事先知道要排序的字段,那么会有很大的 性能提升。在这种情况下,这些字段可以存储为所谓的“文档值字段”,这比传统的索引反转方法更快且更节省内存。

为此,Hibernate Search 提供了 新注解 @SortableField(及其多值伴侣 @SortableFields),用于标记那些应该可用于排序的字段。以下示例显示了如何实现它。

@Entity
@Indexed(index = "Book")
public class Book {

    @Id
    private Integer id;

    @Field
    @SortableField
    @DateBridge(resolution = Resolution.DAY)
    private Date publicationDate;

    @Fields({
        @Field,
        @Field(name = "sortTitle", analyze = Analyze.NO, store = Store.NO, index = Index.NO)
    })
    @SortableField(forField = "sortTitle")
    private String title;

    @Field
    private String summary;

    // constructor, getters, setters ...
}

@SortableField 与已知的 @Field 注解一起使用。如果一个属性只有一个字段(例如 publicationDate),只需指定 @SortableField 注解即可使该字段可排序。如果有多个字段(如 title 属性所示),请通过 @SortableField#forField() 指定字段名称。

请注意,排序字段不应被分析。如果您想为了搜索目的对某个属性进行索引分析,只需添加另一个未分析的排序字段,如 title 属性所示。如果字段仅用于排序且不需要其他用途,您可以将其配置为未索引和未存储,从而避免索引增长。

对于使用配置的排序字段进行查询,当查询时没有任何变化。只需指定一个包含所需字段(s)的 Sort

FullTextQuery query = ...;
Sort sort = new Sort(
    new SortField( "publicationDate", SortField.Type.LONG, false ),
    new SortField( "sortTitle", SortField.Type.STRING, false )
);
query.setSort( sort );

现在假设您对未明确声明为可排序的字段进行排序会发生什么,例如在将现有应用程序迁移到Hibernate Search 5.5时?好消息是,从功能角度来看,排序将按预期应用。Hibernate Search检测到缺失的排序字段,并透明地回退到索引反转

但请注意,这会带来性能损失(它也非常内存密集,因为反转是仅RAM的操作)并且,在未来版本中,这个功能甚至可能会从Lucene中完全移除。因此,请留意日志文件中以下信息,并按照建议声明缺失的排序字段

WARN ManagedMultiReader:142 - HSEARCH000289: Requested sort field(s) summary_forSort are not configured for entity \
type org.hibernate.search.test.query.Book mapped to index Book, thus an uninverting reader must be created. You \
should declare the missing sort fields using @SortField.

在迁移现有应用程序时,请确保按照参考指南中所述重新构建受影响的索引。

配置了所有必要的排序字段后,您的搜索结果将按顺序排列,就像被Mr. Speaker召集秩序的英国议会成员一样。


返回顶部