views:

80

answers:

1

It's a weird problem but every time I add a new document to Lucene.net it overrides the last one and thus it always holds the last inserted document. I've confirmed this behavior using LUKE which lets me open the index files. I'd appreciate if someone could shed light on the problem. Here is my code:

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

I add documents like this:

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

and search for it like this:

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

The true here:

new IndexWriter(indexFileLocation, analyzer, true);

tells Lucene to create a new index, deleting the old one.

RichieHindle
Thanks for your response. Should this always be false or should I conditionally pass this value based on whether the directory already index data?
Am
You need to call it with `true` once to create the index. You can do this in separate code from your document-adding code - it's quite normal to do `indexWriter = new IndexWriter(..., true); indexWriter.Close()` just to create the index, and then later on do `indexWriter = new IndexWriter(..., false);` to write to it.
RichieHindle
Tried your suggestion and its working like a charm:Boolean createNewIndexFile = indexFileLocation.List().Length == 0;IndexWriter indexWriter = new IndexWriter(indexFileLocation, analyzer, createNewIndexFile);
Am