2015-10-27 6 views
17

Vor kurzem haben wir ein CMS arbeiten wir an einem Upgrade und hatte sich bewegen von Lucene.net V2.3.1.301 zu V2.9.4.1Lucene Zurückgeben von Dokumenten mit nicht positive Punktzahl

Wir haben eine CustomScoreQuery in unserer ursprünglichen Lösung, die verschiedene Filterungen durchgeführt hat, die mit den eingebauten Abfragen nicht erreicht werden konnten. (GEO, Multi Datumsbereich usw.)

Da von der alten Version auf die neue Version von Lucene zu bewegen begann es Dokumente Rückkehr, obwohl sie eine 0 oder sogar negative Zahl Punktzahl haben, wenn wir die Ergebnisse prüfen

enter image description here im Folgenden finden Sie eine Probe des refatored Code, um das Problem

public LuceneTest() 
    { 
     Lucene.Net.Store.Directory luceneIndexDirectory = FSDirectory.Open(new System.IO.DirectoryInfo(@"C:\inetpub\wwwroot\Project\build\Data\indexes\all_site_search_en")); 
     Analyzer analyzer = new WhitespaceAnalyzer(); 
     IndexSearcher searcher = new IndexSearcher(luceneIndexDirectory, true); 
     QueryParser parser = new QueryParser(Lucene.Net.Util.Version.LUCENE_23, "", analyzer); 
     parser.SetAllowLeadingWildcard(true); 
     Query dateQuery = ComposeEventDateQuery(new DateTime(2015, 11, 23), new DateTime(2015,11,25), searcher); 
     BooleanQuery combinedQuery = new BooleanQuery(); 
     BooleanQuery.SetMaxClauseCount(10000); 
     combinedQuery.Add(dateQuery, BooleanClause.Occur.MUST); 

     TopDocs hitsFound = searcher.Search(dateQuery, 1000); 
     System.Console.WriteLine(String.Format("Found {0} matches with the date filters", hitsFound.TotalHits)); 
     System.Console.ReadKey(); 
    } 



    public static Query ComposeEventDateQuery(DateTime fromDate, DateTime ToDate, IndexSearcher MySearcher) 
    { 
     BooleanQuery query = new BooleanQuery(); 
     Query boolQuery3A = new TermQuery(new Lucene.Net.Index.Term("_language", "en")); 
     Query eventDateQuery = new EventDateQuery1(boolQuery3A, MySearcher, fromDate, ToDate, false); 
     query.Add(eventDateQuery, BooleanClause.Occur.MUST); 
     return query; 
    } 


    public class EventDateQuery1 : CustomScoreQuery 
    { 
     private Searcher _searcher; 
     private DateTime _fromDT; 
     private DateTime _toDT; 
     private readonly string _dateFormat = "yyyyMMdd"; 

     private bool _shouldMatchNonEvents = true; 

     public EventDateQuery1(Query subQuery, Searcher searcher, DateTime fromDT, bool shouldMatchNonEvents, int dateRange = 14) 
      : base(subQuery) 
     { 
      _searcher = searcher; 
      _fromDT = fromDT.Date; 
      _toDT = fromDT.AddDays(dateRange).Date; 
      _shouldMatchNonEvents = shouldMatchNonEvents; 
     } 

     public EventDateQuery1(Query subQuery, Searcher searcher, DateTime fromDT, DateTime toDT, bool shouldMatchNonEvents) 
      : base(subQuery) 
     { 
      _searcher = searcher; 
      _fromDT = fromDT.Date; 
      _toDT = toDT.Date; 
      _shouldMatchNonEvents = shouldMatchNonEvents; 
     } 


     public override string ToString() 
     { 
      return GenerateUniqueKey(); 
     } 

     public override string ToString(string field) 
     { 
      return GenerateUniqueKey(); 
     } 

     public override string Name() 
     { 
      return GenerateUniqueKey(); 
     } 

     public string GenerateUniqueKey() 
     { 
      return String.Format("EventDateQuery_{0}_{1}_{2}", _fromDT.ToString(_dateFormat), _toDT.ToString(_dateFormat), _shouldMatchNonEvents.ToString()); 
     } 

     protected override CustomScoreProvider GetCustomScoreProvider(IndexReader reader) 
     { 
      return new EventDateQueryCustomScoreProvider(reader, _fromDT, _toDT, _shouldMatchNonEvents); 
     } 



    } 

    public class EventDateQueryCustomScoreProvider : CustomScoreProvider 
    { 
     private DateTime _fromDT; 
     private DateTime _toDT; 
     private readonly string _dateFormat = "yyyyMMdd"; 
     private bool _shouldMatchNonEvents = true; 
     private float NoMatchFloat = 0f; 
     private float MatchFloat = 1f; 

     public EventDateQueryCustomScoreProvider(IndexReader reader, DateTime fromDT, DateTime toDT, bool shouldMatchNonEvents) 
      : base(reader) 
     { 
      _fromDT = fromDT.Date; 
      _toDT = toDT.Date; 
      _shouldMatchNonEvents = shouldMatchNonEvents; 
     } 



     public override float CustomScore(int doc, float subQueryScore, float valSrcScore) 
     { 
      return myScore(doc); 
     } 

     public override float CustomScore(int doc, float subQueryScore, float[] valSrcScores) 
     { 
      return myScore(doc); 
     } 

     public float myScore(int doc) 
     { 
      //Below is a fake implementation just to prove the run 
      if (doc < 10) 
      { 
       return 1F; 
      } 
      else 
      { 
       return 0F; 
      } 
     } 



    } 

Irgendwelche Vorschläge auf zeigen, wie man es nicht haben Lucene diese Dokumente zurückgeben groß werden würde. Vielen Dank im Voraus.

Antwort

6

Sie können eine benutzerdefinierte Collector schreiben, die nur Dokumente mit >0 Score sammelt. Übergeben Sie dann eine Instanz dieses Kollektors an die Methode Search(). Es gibt eine Implementierung eines solchen Collectorhere. Die documentation schlägt jedoch gegen diese Lösung vor, wenn Sie nicht alle Ergebnisse benötigen. Dies ist wahrscheinlich der Fall, da Sie nur die Top 1000 Dokumente auswählen.