2021-05-12 14:32:11
在 Hibernate Search 5.5 中對搜尋結果進行排序
“秩序,秩序”- 有時不僅僅下議院尊敬的議員需要被喊著讓排序,而且在特殊情況下 Hibernate 的查詢結果也需要排序。
就像這樣,僅僅通過一個 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 屬性的顯示。如果欄位僅僅需要排序而不做其他事,你需要將它設定成非索引和非排序的,因此可避免不必要的索引被生成。
在不改變查詢的情況下,對排序欄位的設定。僅對需要的欄位設定 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 檢測到未設定排序欄位,自然就回退到非倒排索引。
但是你要知道這樣做的話效能會差很多(同樣也是作為非反轉記憶體操作的記憶體密集型),也許這個功能將要從 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.
當遷移一個存在的專案,一定要重建有效的索引,這在相關指導裡有詳細描述。隨著所有的需要排序欄位被設定,你的查詢結果會被排序,就像是會議主持喊著讓英國的議會會員排隊那樣。
相關文章