Как правильно перестроить индекс Lucene? - PullRequest
1 голос
/ 24 июля 2010

У меня есть форум, похожий на веб-приложение, написанное на Asp.net MVC. Я пытаюсь реализовать Lucene.net в качестве поисковой системы. Когда я строю свой индекс, время от времени я получаю исключения, связанные с тем, что Lucene не может переименовать файл deletable. Я думаю, это потому, что я очищаю индекс каждый раз, когда хочу его перестроить. Вот код, который занимается индексацией:

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

А вот код, который выполняет все это:

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

Почему Lucene жалуется на переименование «удаляемого» файла?

Ответы [ 2 ]

2 голосов
/ 25 июля 2010

Не уверен, почему вы воссоздаете индекс каждый раз. Вы можете добавить к индексу следующим образом:

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

Флаг false в конце указывает IndexWriter открываться в режиме добавления (т. Е. Не перезаписывать). Это может заставить вашу проблему уйти.

0 голосов
/ 26 июля 2010

Оказалось, что если индексные файлы не существуют, то создание IndexReader перед IndexWriter не является хорошей идеей.Я также понял, что хотя метод AddDocument в IndexWriter имеет две перегрузки (одна с параметром анализатора и один без), у меня работает только та, у которой есть параметр анализатора.

...