2010-04-14 4 views
0

C'est un problème étrange mais chaque fois que j'ajoute un nouveau document à Lucene.net il remplace le dernier et donc il contient toujours le dernier document inséré. J'ai confirmé ce comportement en utilisant LUKE qui me permet d'ouvrir les fichiers d'index. J'apprécierais que quelqu'un puisse faire la lumière sur le problème. Voici mon code:Lucene.net ne contient que le dernier document ajouté

public class SearchService : ISearchService 
{ 
    Directory indexFileLocation; 
    Analyzer analyzer; 

    public SearchService(String indexLocation) 
    { 
     indexFileLocation = FSDirectory.GetDirectory(indexLocation, true); 
     analyzer = new StandardAnalyzer(); 
    } 

    public void AddToSearchIndex(ISearchableData data) 
    { 
     IndexWriter indexWriter = new IndexWriter(indexFileLocation, analyzer, true); 
     Document doc   = new Document(); 

     foreach (var entry in data) 
     { 
      Field field = new Field(
       entry.Key, 
       entry.Value, 
       Lucene.Net.Documents.Field.Store.NO, 
       Lucene.Net.Documents.Field.Index.TOKENIZED, 
       Lucene.Net.Documents.Field.TermVector.WITH_POSITIONS_OFFSETS); 

      doc.Add(field); 
     } 

     Field keyField = new Field(
      SearchField.Key.ToString(), 
      data.Key, 
      Lucene.Net.Documents.Field.Store.YES, 
      Lucene.Net.Documents.Field.Index.UN_TOKENIZED); 

     doc  .Add(keyField); 
     indexWriter.AddDocument(doc); 
     indexWriter.Optimize(); 
     indexWriter.Close(); 
    } 

    public IDictionary<Int32, float> SearchContent(String term) 
    { 
     IndexSearcher searcher = new IndexSearcher(indexFileLocation); 
     TermQuery  query = new TermQuery(new Term(SearchField.Content.ToString(), term)); 
     Hits   hits = searcher.Search(query); 
     searcher.Close(); 

     return OrganizeSearchResults(hits); 
    } 

    public IDictionary<Int32, float> OrganizeSearchResults(Hits hits) 
    { 
     IDictionary<Int32, float> result = new Dictionary<Int32, float>(); 
     String keyField = SearchField.Key.ToString(); 

     for (int i = 0; i < hits.Length(); i++) 
     { 
      Document doc = hits.Doc(i); 
      Field field = doc.GetField(keyField); 
      result.Add(Int32.Parse(
       field.StringValue()), 
       hits.Score(i)); 
     } 

     return result; 
    } 
} 

ajouter des documents comme celui-ci:

new SearchService(searchIndexFolderPath).AddToSearchIndex(entry.ToSearchableData()); 

et cherche comme ceci:

ISearchService search = new SearchService(MvcApplication.SearchIndexPath); 
IList<Int32> submissionIds = search.SearchContent(SearchTerm).Select(hit => hit.Key).ToList<Int32>(); 

Répondre

0

Le true ici:

new IndexWriter(indexFileLocation, analyzer, true); 

dit à Lucene de créer un nouvel index, supprimant l'ancien.

+0

Merci pour votre réponse. Est-ce que cela devrait toujours être faux ou devrais-je transmettre conditionnellement cette valeur selon que le répertoire répertorie déjà les données? – Roman

+0

Vous devez l'appeler avec 'true' une fois pour créer l'index. Vous pouvez le faire dans un code séparé de votre code d'ajout de document - il est tout à fait normal de faire 'indexWriter = new IndexWriter (..., true); indexWriter.Close() 'juste pour créer l'index, puis plus tard' indexWriter = new IndexWriter (..., false); 'pour y écrire. – RichieHindle

+0

Essayé votre suggestion et son fonctionnement comme un charme: Boolean createNewIndexFile = indexFileLocation.List(). Longueur == 0; IndexWriter indexWriter = new IndexWriter (indexFileLocation, analyseur, createNewIndexFile); – Roman

Questions connexes