2010-03-29 1 views
7

Ich habe einen Index mit verschiedenen Datenbits für jedes Dokument erstellt, das ich hinzugefügt habe, kann jedes Dokument in Feldnamen unterscheiden.Lucene.NET und Suche nach mehreren Feldern mit bestimmten Werten

Später, als ich gekommen, um den Index ich es mit dem genauen Feld/Werten abfragen müssen suchen - zum Beispiel:

FieldName1 = X AND FieldName2 = Y AND FieldName3 = Z 

Was ist der beste Weg, um die von der Konstruktion folgenden mit Lucene .NET:

  • Welcher Analysator ist für diesen genauen Übereinstimmungstyp am besten geeignet?
  • Nach dem Abrufen einer Übereinstimmung, ich brauche nur ein bestimmtes Feld zurückgegeben werden (die ich jedem Dokument hinzufügen) - sollte dies die einzige gespeichert werden?
  • Später muss ich die Stichwortsuche unterstützen (so kann ein Feld eine Liste von Werten haben und ich muss eine Teilübereinstimmung machen).

Die Felder und Werte stammen von Dictionary<string, string>. Es ist keine Benutzereingabe, es besteht aus Code.

Danke,
Kieron

Antwort

7

Nun, ich dachte, es schließlich aus - mein nehmen auf sie hier ist (dies völlig falsch sein könnte, aber es funktioniert für):

public Guid? Find (Dictionary<string, string> searchTerms) 
{ 
    if (searchTerms == null) 
     throw new ArgumentNullException ("searchTerms"); 

    try 
    { 
      var directory = FSDirectory.Open (new DirectoryInfo (IndexRoot)); 
      if (!IndexReader.IndexExists (directory)) 
       return null; 

      var mainQuery = new BooleanQuery(); 
      foreach (var pair in searchTerms) 
      { 
       var parser = new QueryParser (
        Lucene.Net.Util.Version.LUCENE_CURRENT, pair.Key, GetAnalyzer()); 
       var query = parser.Parse (pair.Value); 

       mainQuery.Add (query, BooleanClause.Occur.MUST); 
      } 

      var searcher = new IndexSearcher (directory, true); 

      try 
      { 
       var results = searcher.Search (mainQuery, (Filter)null, 10); 
       if (results.totalHits != 1) 
        return null; 

       return Guid.Parse (searcher.Doc (results.scoreDocs[0].doc).Get (ContentIdKey)); 
      } 
      catch 
      { 
       throw; 
      } 
      finally 
      { 
       if (searcher != null) 
        searcher.Close(); 
      } 
    } 
    catch 
    { 
      throw; 
    } 
}