我有两个单独的课程 -MyIndexer
和MySearcher
. indexer 类工作正常,并生成一个可以用 Luke 浏览的索引。我看到里面的文档。我使用 Lucene 4.0.0 只是为了查看使用 Luke 的数据。
我有一个带有两种测试方法的 JUnit 测试类。第一个调用索引器并创建索引。然后它关闭索引器的阅读器。然后执行第二个测试方法并尝试搜索结果。
我收到以下错误:
org.apache.lucene.store.AlreadyClosedException: this IndexReader is closed
at org.apache.lucene.index.IndexReader.ensureOpen(IndexReader.java:252)
at org.apache.lucene.index.SegmentReader.fields(SegmentReader.java:147)
at org.apache.lucene.index.TermContext.build(TermContext.java:90)
at org.apache.lucene.search.TermQuery.createWeight(TermQuery.java:167)
at org.apache.lucene.search.IndexSearcher.createNormalizedWeight(IndexSearcher.java:647)
at org.apache.lucene.search.IndexSearcher.search(IndexSearcher.java:292)
at com.foo.MySearcher.findArtifacts(MySearcher.java:76) // Line pointer shown in comments below
... (more irrelevant stacks)
MyIndexer
相关摘录:
public class MyIndexer
{
private IndexWriter writer;
private IndexConfiguration indexConfiguration;
public MyIndexer()
{
}
public void initialize()
throws IOException
{
StandardAnalyzer analyzer = new StandardAnalyzer(indexConfiguration.getLuceneVersion());
final File indexDir = new File(indexConfiguration.getIndexDirectory()).getCanonicalFile();
final FSDirectory index = FSDirectory.open(indexDir);
IndexWriterConfig config = new IndexWriterConfig(indexConfiguration.getLuceneVersion(), analyzer);
writer = new IndexWriter(index, config);
}
public void addData()
throws IOException
{
// ...
// Add some data here
// ...
writer.addDocument(doc);
}
public void close()
throws IOException
{
if (writer != null)
{
writer.commit();
writer.close();
}
}
public IndexWriter getWriter()
{
return writer;
}
public void setWriter(IndexWriter writer)
{
this.writer = writer;
}
public IndexConfiguration getIndexConfiguration()
{
return indexConfiguration;
}
public void setIndexConfiguration(IndexConfiguration indexConfiguration)
{
this.indexConfiguration = indexConfiguration;
}
}
MySearcher
:
public class MySearcher
{
private IndexReader reader;
private IndexSearcher searcher;
private IndexConfiguration indexConfiguration;
public MySearcher()
{
}
public void initialize()
throws IOException
{
final File indexDir = new File(indexConfiguration.getIndexDirectory()).getCanonicalFile();
final FSDirectory index = FSDirectory.open(indexDir);
reader = DirectoryReader.open(index);
searcher = new IndexSearcher(reader);
}
// This method is currently void for the sake of testing:
public void findData(...)
throws IOException
{
int hitsPerPage = 10;
BooleanQuery query = new BooleanQuery();
// ...
// Does some irrelevant query-related stuff
// ...
TopScoreDocCollector collector = TopScoreDocCollector.create(hitsPerPage, true);
searcher.search(query, collector); // Place where the exception occurs.
ScoreDoc[] hits = collector.topDocs().scoreDocs;
System.out.println("Found " + hits.length + " hits.");
for (int i = 0; i < hits.length; ++i)
{
int docId = hits[i].doc;
Document document = searcher.doc(docId);
System.out.println(/*... Should print out some data from each matching document's fields */);
}
reader.close();
}
public IndexReader getReader()
{
return reader;
}
public void setReader(IndexReader reader)
{
this.reader = reader;
}
public IndexSearcher getSearcher()
{
return searcher;
}
public void setSearcher(IndexSearcher searcher)
{
this.searcher = searcher;
}
public IndexConfiguration getIndexConfiguration()
{
return indexConfiguration;
}
public void setIndexConfiguration(IndexConfiguration indexConfiguration)
{
this.indexConfiguration = indexConfiguration;
}
}
MyLuceneTest:
public class MyLuceneTest
{
public static final String INDEX_DIR = "target/test-indexes/index-001";
private static IndexConfiguration configuration;
@Before
public void setUp()
throws Exception
{
configuration = new IndexConfiguration();
configuration.setIndexDirectory(INDEX_DIR);
}
@Test
public void testVerboseIndexing()
throws IOException
{
MyIndexer indexer = new MyIndexer();
indexer.setIndexConfiguration(configuration);
indexer.initialize();
// Adding some data here
...
indexer.addData(...);
...
indexer.close();
// Obviously, we're not doing any assertions right now.
}
@Test
public void testSearch()
throws IOException
{
MySearcher searcher = new MySearcher();
searcher.setIndexConfiguration(configuration);
searcher.initialize();
searcher.findData(...);
searcher.findData(...);
searcher.findData(...);
// Obviously, we're not doing any assertions right now.
}
}
所以...这里有什么交易...?一旦索引器停止执行并且应用程序完成后,如何正常打开索引?我显然在做一些愚蠢的事情,因为我相信你以后可以重新打开索引。