2010-03-29 8 views
7

J'ai créé un index avec différents bits de données pour chaque document que j'ai ajouté, chaque document peut différer dans son nom de champ.Lucene.NET et la recherche sur plusieurs champs avec des valeurs spécifiques

Plus tard, quand je viens chercher l'index je dois l'interroger avec le champ/valeurs exactes - par exemple:

FieldName1 = X AND FieldName2 = Y AND FieldName3 = Z 

Quelle est la meilleure façon de construire les éléments suivants en utilisant Lucene .NET:

  • Quel analyseur convient le mieux pour ce type de correspondance exacte?
  • Lors de la récupération d'une correspondance, j'ai seulement besoin d'un champ spécifique à renvoyer (que j'ajoute à chaque document) - devrait-il être le seul stocké?
  • Plus tard, je devrai prendre en charge la recherche par mot-clé (ainsi un champ peut avoir une liste de valeurs et je dois faire une correspondance partielle).

Les champs et les valeurs proviennent d'un Dictionary<string, string>. Ce n'est pas une entrée de l'utilisateur, c'est construit à partir du code.

Merci,
Kieron

Répondre

7

Eh bien, j'ai tout compris par la suite - voici mon avis sur la question (cela pourrait être tout à fait tort, mais cela fonctionne pour):

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