2010-12-21 103 views
6

我有問題,在.NET中排序我的lucene.net索引。我嘗試了幾乎每個解決方案在stackoverflow和尋找谷歌的答案。我正在使用Lucene.NET 2.9.2和ASP.NET 2.0。我想對字符串進行排序,就像在sql中一樣,你可以鍵入'order by title desc [asc]'Lucene.net 2.9.2排序(排序不起作用)

我會告訴你我的代碼,我希望有人能幫助我。

//Here I create Index with some fields 
    doc.Add(new Field("prod_id",row["prod_id"].ToString(),Field.Store.YES,Field.Index.ANALYZED)); 
      doc.Add(new Field("prod_title", row["prod_title"].ToString(), Field.Store.YES, Field.Index.ANALYZED)); 
      doc.Add(new Field("prod_desc", row["prod_desc"].ToString(), Field.Store.YES, Field.Index.ANALYZED)); 
      doc.Add(new Field("prod_author", row["prod_author"].ToString(), Field.Store.YES, Field.Index.ANALYZED)); 
      doc.Add(new Field("prod_publisher", row["prod_publisher"].ToString(), Field.Store.YES, Field.Index.ANALYZED)); 
      doc.Add(new Field("prod_price", row["prod_price"].ToString(), Field.Store.YES, Field.Index.ANALYZED)); 

//Then next I try to do search with sort option: 

//method for return approciate Sort object 
private static Sort SetSortForLucene(string _sort) 
    { 
     Sort sort; 
     switch (_sort) 
     { 
      case "UnitPriceGorss": 
       sort = new Sort(new SortField("prod_price",SortField.DOUBLE,false); 
       break; 

      case "UnitPriceGorssDESC": 
       sort = new Sort(new SortField("prod_price",SortField.DOUBLE,true); 
       break; 

      case "Title": 
       //not working 
       sort = new Sort(new SortField("prod_title", SortField.STRING, true)); 
       break; 

      case "TitleDESC": 
       //not working 
       sort = new Sort(new SortField("prod_title", SortField.STRING, false)); 
       break; 
      case "": 
       sort = new Sort(new SortField("prod_title", SortField.STRING, false)); 
       break; 
      default: 
       sort = new Sort(new SortField("prod_title", SortField.STRING, false)); 
       break; 
     } 
     return sort; 
    } 
//Inside my query of lucene method: 
StandardAnalyzer analizer = new StandardAnalyzer(Version.LUCENE_29); 
IndexReader reader =IndexReader.Open(IndexPath); 
Searcher searcher = new IndexSearcher(reader); 
//Here call for Sort object 
Sort sort = SetSortForLucene(_sort); 
TopFieldDocCollector collector = new TopFieldDocCollector(reader, sort, pageSize); 
//Find which document field need to me asked in QueryParser object 
string _luceneField = ""; 

     if (luceneField.Contains("_")) 
      _luceneField = luceneField; 
     else 
     switch (luceneField) 
     { 
      case "Title": _luceneField = "prod_title"; break; 
      case "Description": _luceneField = "prod_desc"; break; 
      case "Author": _luceneField = "prod_author"; break; 
      case "Publisher": _luceneField = "prod_publisher"; break; 
      default: _luceneField = "prod_title"; break; 
     } 
     QueryParser parser = new QueryParser(_luceneField, analizer); 
     Query query = parser.Parse(luceneQuery); 
     ScoreDoc[] hits; 
     searcher.Search(query,collector); 
//Obtaining top records from search but without any sort. 
     hits = collector.TopDocs().scoreDocs; 

     foreach (ScoreDoc hit in hits) 
     { 
      Document doc = searcher.Doc(hit.doc); 
      string a = doc.Get("prod_id"); 
      int id = 0; 
      if (hit.score > score) 
      { 
       if (int.TryParse(doc.Get("prod_id"), out id)) 
           tmpId.Add(id); 
      } 
     } 
//I also define stop words for full text searching and i think this is 
//real cause of problem with sorting. 
System.String[] stopWords = new System.String[]{"a","że","w","przy","o","bo","co","z","za","ze","ta","i","no","do"}; 

我用這個link in stackoverflow.this pretty one link解決我的問題,但排序失敗,我不知道什麼是錯我的代碼。

幾天後終於找到了解決辦法。當我想排序的字段表示字符串值時,它不會被標記。

例如,當我想標題(升/降),以產品分類,你應該把這樣的事情:

doc.Add(new Field(Product.PROD_TITLE_SORT, row["prod_title"].ToString().Replace(" ", "_") + "_" + row[Product.PROD_ID].ToString(), Field.Store.NO, Field.Index.NOT_ANALYZED)); 

我不明白的是爲什麼實際上這個領域並不存儲和不analizyng因此lucene.net可以通過這個添加的字段進行排序。這種排序領域甚至不在索引!我使用lukeall-1.0.1.jar索引瀏覽器進行了檢查。

其次,你需要創建一個適當的排序方法:

private static Sort SetSortForLucene(string _sort) 
     { 
      Sort sort; 
      _sort = !string.IsNullOrEmpty(_sort) ? _sort : ""; 
      switch (_sort) 
      { 
       case "UnitPriceGorss": 
        sort = new Sort(new SortField(PROD_PRICE, SortField.DOUBLE, false)); 
        break; 

       case "UnitPriceGorssDESC": 
        sort = new Sort(new SortField(PROD_PRICE, SortField.DOUBLE, true)); 
        break; 

       case "Title": 
        //not it works perfectly. 
        sort = new Sort(new SortField(PROD_TITLE_SORT, SortField.STRING, true)); 
        break; 

       case "TitleDESC": 
        //not it works perfectly. 
        sort = new Sort(new SortField(PROD_TITLE_SORT, SortField.STRING, false)); 
        break; 
       case ""://Here is default sorting behavior. It get's result according to Lucene.NET search result score. 
        sort = new Sort(SortField.FIELD_SCORE); 
        break; 
       default: 
        sort = new Sort(SortField.FIELD_SCORE); 
        break; 
      } 
      return sort; 
     } 

是什麼讓我真的懷疑是那種可與SortField.DOUBLE場時,在Lucene的全文索引被索引。

我希望這篇文章能夠幫助任何有類似排序問題的人。

回答

6

該字段不需要存儲,除非您要在查詢中返回數據。但是它仍然被添加到索引中。

你不分析你想分類的字段的原因是分析器將字段分成單獨的條件,這使得排序非常困難,因爲文檔的索引會有多個單詞,顯然不能按照整個指數排序。這適用於所有字段類型,不管它們是否是單個字段。

我相信你可以存儲字段,但除非你想在你的查詢返回它,沒有必要。

4

我懷疑有關排序的一件重要的事情。

它不適用於標記化(分析)的數據。

+0

因此....爲您希望排序的數據添加一個未分析字段,並將其用於排序,如果您還希望對其進行分析,則可能必須複製該字段。 – Myster 2014-07-17 03:41:38