1

我有一个将文档写入我的索引的索引管理器类。当我将一个 RAMDirectory 传递给它以创建一个 IndexWriter 时,我在文件segments.gen 上得到一个 FileNotFoundException

这是我的课:

public class IndexManager
{
    private readonly IIndexPersistable _indexPersister;

    public IndexManager(IIndexPersistable indexPersister)
    {
        _indexPersister = indexPersister;
    }

    public Directory Directory
    {
        get { return _indexPersister.Directory; }
    }

    internal void WriteDocumentsToIndex(
        IEnumerable<Document> documents, 
        bool recreateIndex)
    {
        using(var writer = 
            new IndexWriter(
                Directory, 
                new StandardAnalyzer(LuceneVersion.LUCENE_30), 
                recreateIndex,
                IndexWriter.MaxFieldLength.UNLIMITED))
        {
            foreach (Document document in documents)
            {
                writer.AddDocument(document);
            }

            writer.Optimize();
        }
    }
}


public class InMemoryPersister : IIndexPersistable
{
    private readonly Directory _directory;

    public InMemoryPersister()
    {
        _directory = new RAMDirectory();
    }

    public Directory Directory
    {
        get { return _directory; }
    }
}

这是单元测试方法:

[TestMethod]
    public void TestMethod1()
    {
        using (var manager = new IndexManager(new InMemoryPersister()))
        {
            IList<Recipe> recipes = Repositories.RecipeRepo.GetAllRecipes().ToList();
            IEnumerable<Document> documents = recipes.Select(RecipeIndexer.IndexRecipe);
            manager.WriteDocumentsToIndex(documents, true);
        }
    }

我尝试了几种不同的排列,但在这个解决方案中,我总是得到 FileNotFoundException。我在一个运行良好的测试解决方案中有另一个非常相似的实现。我还多次修改了这个解决方案,以便在创建新的 IndexWriter 时简单地声明一个新的 RAMDirectory,但这也失败了。

非常感谢帮助/建议。如果我需要澄清任何事情,请告诉我。

4

2 回答 2

2

我在 CLR 异常上启用了中断。Lucene 正在抛出异常并会处理它们,但我正在中断该过程。一旦我禁用了 CLR 异常中断,我的测试就使用 RAMDirectory 成功运行。

于 2015-03-05T23:23:58.340 回答
1

如果 create 参数为 false 并且 Directory 尚不包含索引,则 Index Writer 将引发 FileNotFound 异常。并且使用 RAMDirectory,第一次在其上打开 IndexWriter 时,它不会有索引。如果您希望它创建索引,则可以传递IndexReader.IndexExists(Directory) || recreate给构造函数,而不仅仅是recreate.

另一种选择是使用一个没有 create 参数的 IndexWriter 构造函数,如果索引不存在,它将创建索引,如果存在则打开现有索引。

于 2013-10-11T23:46:07.537 回答