开发者

What is the correct way to rebuild Lucene's index

I have a forum like web application written in Asp.net MVC. I'm trying to implement Lucene.net as the search engine. When I build my index, every now and then I get exceptions related to Lucene not being able to rename the deletable file. I think it's because I empty the index 开发者_如何学Pythonevery time I want to rebuild it. Here is the code that deals with indexing:

public class SearchService : ISearchService
{
    Directory   IndexFileLocation;
    IndexWriter Writer;
    IndexReader Reader; 
    Analyzer    Analyzer;

    public SearchService(String indexLocation)
    {
        IndexFileLocation = FSDirectory.GetDirectory(indexLocation, System.IO.Directory.Exists(indexLocation) == false);
        Reader            = IndexReader.Open(IndexFileLocation);
        Writer            = new IndexWriter(IndexFileLocation, Analyzer, IndexFileLocation.List().Length == 0);
        Analyzer          = new StandardAnalyzer();
    }

    public void ClearIndex()
    {
        var DocumentCount = Writer.DocCount();
        if (DocumentCount == 0)
            return;

        for (int i = 0; i < DocumentCount; i++)
            Reader.DeleteDocument(i);
    }

    public void AddToSearchIndex(ISearchableData Data)
    {
        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.NO);

        Doc.Add(KeyField);
        Writer.AddDocument(Doc);
    }

    public void Dispose()
    {
        Writer.Optimize();
        Writer.Close();
        Reader.Close();
    }
}

And here is the code that executes it all:

    private void btnRebuildIndex_Click(object sender, EventArgs e)
    {
        using (var SearchService = new SearchService(Application.StartupPath + @"\indexs\"))
        {
            SearchService.ClearIndex();
        }

        using (var SearchService = new SearchService(Application.StartupPath + @"\indexs\"))
        {
            Int32 BatchSize = 50;
            Int32 Current = 0;
            var TotalQuestions = SubmissionService.GetQuestionsCount();

            while (Current < TotalQuestions)
            {
                var Questions = SubmissionService.ListQuestions(Current, BatchSize, "Id", Qsparx.SortOrder.Asc);

                foreach (var Question in Questions)
                {
                    SearchService.AddToSearchIndex(Question.ToSearchableData());
                }

                Current += BatchSize;
            }
        }
    }

Why does Lucene complain about renaming the "deletable" file?


Not sure why you are recreating the index everytime. You can append to the index thus:

Writer = new IndexWriter(IndexFileLocation, Analyzer,false);

The false flag at the end tells the IndexWriter to open in append mode(i.e. not overwrite). That might make your problem go away.


It turned out, if no index files exist, then creating an IndexReader before an IndexWriter is not a good idea. I also realized even though the AddDocument method of IndexWriter has two overloads (one w/ and one w/o Analyzer parameter) only the one with analyzer parameter works for me.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜