2010-12-21 19 views
6

Ich habe Probleme mit der Sortierung meines lucene.net Indexes in .NET. Ich habe fast jede Lösung auf Stackoverflow ausprobiert und nach google Antworten gesucht. Ich benutze Lucene.NET 2.9.2 und ASP.NET 2.0. Ich möchte über String wie in Sql sortieren Sie können 'bestellen nach Titel desc [asc]'Lucene.net 2.9.2 Sortierung (Sortierung funktioniert nicht)

Ich werde Ihnen meinen Code zeigen und ich hoffe, jemand kann mir helfen.

//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"}; 

ich verwenden, um diesen link in stackoverflow. und this pretty one link mein Problem zu lösen, aber Sortierung versagt, und ich weiß nicht, was mit meinem Code falsch ist.

Nach ein paar Tagen fand ich endlich eine Lösung. Das Feld, das ich sortieren möchte, sollte nicht in Token umgewandelt werden, wenn es einen String-Wert repräsentiert.

Zum Beispiel, wenn ich Produkte nach Titel (Aufstiegs-/Abstiegs) sortieren möchten, sollten Sie etwas so:

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)); 

Was ich nicht bekommen Tatsache ist, warum dieses Feld nicht und nicht analizyng speichert und somit kann lucene.net nach diesem zusätzlichen Feld sortieren. Dieses Sortierfeld ist nicht im Index !! Ich überprüfte mit lukeall-1.0.1.jar Indexbrowser.

Zweitens benötigen Sie eine geeignete Sortiermethode zu erstellen:

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; 
     } 

Was macht mich wirklich verdächtig ist, dass Art arbeitet mit SortField.DOUBLE wenn Feld in lucene Volltextindex indiziert ist.

Ich hoffe dieser Beitrag wird jedem helfen, der ähnliches Problem mit dem Sortieren hat.

Antwort

6

Das Feld muss nicht gespeichert werden, es sei denn, Sie geben die Daten in Ihrer Abfrage zurück. Es wird jedoch immer noch zum Index hinzugefügt.

Der Grund, warum Sie ein Feld, das Sie sortieren möchten, nicht analysieren, ist, dass ein Analysator das Feld in separate Begriffe aufteilt, was das Sortieren sehr schwierig macht, da der Index für das Dokument mehrere Wörter enthält sortiert nach dem ganzen Index. Dies gilt für alle Feldtypen, unabhängig davon, ob es sich um einen einzelnen Begriff handelt oder nicht.

Ich glaube, Sie können das Feld speichern, aber wenn Sie es in Ihrer Abfrage nicht zurückgeben möchten, gibt es keine Notwendigkeit.

4

Eine wichtige Sache, die ich über das Sortieren wissen muss.

Es funktioniert nicht mit tokenisierten (analysierten) Daten.

+0

Also .... fügen Sie ein nicht analysiertes Feld für die Daten hinzu, die Sie sortieren möchten, und verwenden Sie das zum Sortieren. Sie müssen das Feld möglicherweise duplizieren, wenn Sie es auch analysieren möchten. – Myster

Verwandte Themen