lucene4.7 之排序(四)

排序是對於全文檢索來言是一個必不可少的功能,在實際運用中,排序功能能在某些時候給咱們帶來很大的方便,好比在淘寶,京東等一些電商網站咱們可能經過排序來快速找到價格最便宜的商品,或者經過排序來找到評論數最高或賣的最好的商品,再好比在Iteye裏的博客欄裏,天天都會以降序的方式,來顯示出最新發出的幾篇博客,有了排序,咱們就能在某些時候很方便快速的獲得某些有效信息,因此說排序功能,無處不在 ^_^。 


那麼,本篇散仙就來看下咱們在Lucene中怎麼使用其豐富的排序功能。 

在這以前,咱們先來熟悉下lucene中排序的基本知識,在默認狀況下,Lucene使用的是以關聯性降序的方式爲默認的排序方式,這樣可使得咱們搜索的結果一般是最優的,由於它會盡量的使得首先出現的幾個結果是與咱們搜索的內容最相關,而不須要咱們翻頁尋找咱們最想要的內容,這一點是與數據庫相比,是全文檢索一個很大的優勢。固然,在實際開發中咱們也須要根據業務的實際狀況來給咱們的客戶提供多種不一樣的排序方式。咱們先來看下在Lucene中比較特殊的兩種基本的排序方式 

java

Sort裏的屬性 SortField裏的屬性 含義
Sort.INDEXORDER SortField.FIELD_DOC 按照索引的順序進行排序
Sort.RELEVANCE SortField.FIELD_SCORE 按照關聯性評分進行排序


咱們再來看幾個檢索時須要用的方法數據庫

 =========SortField類============
//field是排序字段type是排序類型
public SortField(String field, Type type);
//field是排序字段type是排序類型reverse是指定升序仍是降序
//reverse 爲true是降序  false爲升序
  public SortField(String field, Type type, boolean reverse)

  =========Sort類============
  public Sort();//Sort對象構造方法默認是按文檔評分排序
  public Sort(SortField field);//排序的一個SortField
  public Sort(SortField... fields)//排序的多個SortField能夠傳入一個數組
 
  =========IndexSearche類r========
//query是查詢的Query對象 filter是過濾  n返回的數量  sort是排序
search(Query query, Filter filter, int n, Sort sort) 
//doDocScores 爲true狀況下每一個命中的結果下都會被評分
//doMaxScore  爲true狀況下對最大分值的搜索結果進行評分
search(Query query, Filter filter, int n, Sort sort, boolean doDocScores, boolean doMaxScore)
1,在尚未進行一點排序前咱們先來看下索引裏的內容,核心代碼以下:
        TopDocs topDocs=searcher.search(new MatchAllDocsQuery(),10000);

2,使用默認的關聯性評分後,核心代碼和運行效果圖以下:
編程

   Sort sort=new Sort();//默認使用關聯性評分
             TopDocs topDocs=searcher.search(new MatchAllDocsQuery(),10000,sort);

關於上圖中亂碼字符緣由是由於默認排序狀況下lucene是不會對搜索結果進行評分操做的,由於評分操做會下降性能,因此關於score的那一列返回的是NAN的字符串,出於格式的須要,散仙在用DecimalFormat類給其評分結果保留2位小數時,由於是一個特殊字符,因此就出現了上圖狀況。 

3,按照日期降序排序,,核心代碼和運行效果圖以下:
數組

 Sort sort=new Sort(new SortField("date", Type.INT,true));//true爲降序排列
             TopDocs topDocs=searcher.search(new MatchAllDocsQuery(),10000,sort);


4,按照價格升序排序,,核心代碼和運行效果圖以下:
性能

 Sort sort=new Sort(new SortField("price", Type.DOUBLE,false));//false爲降序排列
             TopDocs topDocs=searcher.search(new MatchAllDocsQuery(),10000,sort);

5,多字段排序,按照日期降序的狀況下,由於id爲7和8的日期相同,因此咱們就新增一個排序字段按ename升序排列,,核心代碼和運行效果圖以下:
網站

 // Sort sort=new Sort(new SortField("date", Type.INT, true),new SortField("ename", Type.STRING, false));
            //這兩段代碼效果同樣
            Sort sort=new Sort(new SortField[]{new SortField("date", Type.INT, true),new SortField("ename", Type.STRING, false)});
             TopDocs topDocs=searcher.search(new MatchAllDocsQuery(),10000,sort);

6,帶評分的排序,注意後面兩個布爾類型的變量能夠控制是否評分,特別是在沒有要求須要打分時,建議別開啓,大數量時對性能影響較大,檢索「編程」獲得的結果,默認按評分降序排序,核心代碼和運行效果圖以下:
spa

    Sort sort=Sort.RELEVANCE;
            TopDocs topDocs=searcher.search(new TermQuery(new Term("bookname", "編程")),null,100,sort,true,true);

上面的編程,編程由於在切分時編程的tf出現了2次,因此在查詢時有較高的得分,因此排在首位。 

7,注意幾點 
(1)排序對一個文檔裏什麼域都沒存儲,使用字符串排序會排在首位 
(2)排序對一個文檔裏什麼域都沒存儲,使用數字類型排序會默認給其賦值爲0進行排序 
(3)咱們能夠對數字類型的null值的文檔進行代碼控制,能夠將其設置爲最大,因此將會排在最後面,代碼以下

code

 SortField sortField = new SortField("value", SortField.Type.INT);
    sortField.setMissingValue(Integer.MAX_VALUE);
相關文章
相關標籤/搜索