Lucene的IndexReader.reopen似乎并没有正常工作

问题描述:

我有一个问题,使用Lucene 2.4,这种情况被如下:Lucene的IndexReader.reopen似乎并没有正常工作

我必须处理的可能性,有2个在同一指数运行单独的进程目录,他们需要有相同的数据。这意味着当一个实例向索引添加一个文档时,其他应用程序实例将在其下一个搜索中找到添加的文档。根据Lucene文档,IndexReader.reopen是我需要的。

所以我发明了以下测试用例:

package de.samedi.searcher; 

import static org.junit.Assert.assertEquals; 
import static org.junit.Assert.fail; 

import java.io.IOException; 

import org.apache.lucene.analysis.standard.StandardAnalyzer; 
import org.apache.lucene.document.Document; 
import org.apache.lucene.document.Field; 
import org.apache.lucene.index.CorruptIndexException; 
import org.apache.lucene.index.IndexReader; 
import org.apache.lucene.index.IndexWriter; 
import org.apache.lucene.queryParser.QueryParser; 
import org.apache.lucene.search.IndexSearcher; 
import org.apache.lucene.search.Query; 
import org.apache.lucene.search.TopDocs; 
import org.apache.lucene.store.FSDirectory; 
import org.junit.Test; 

public class LuceneReload { 

    private IndexSearcher searcher1; 
    private IndexSearcher searcher2; 
    private FSDirectory directory1, directory2; 
    private IndexWriter writer1, writer2; 


    @Test 
    public void testReload() throws Exception { 
     String home = System.getProperty("user.home"); 
     this.directory1 = FSDirectory.getDirectory(home + "/testIndex"); 
     this.directory2 = FSDirectory.getDirectory(home + "/testIndex"); 
     this.writer1 = new IndexWriter(this.directory1, new StandardAnalyzer(), true, IndexWriter.MaxFieldLength.LIMITED); 
     this.writer2 = new IndexWriter(this.directory2, new StandardAnalyzer(), true, IndexWriter.MaxFieldLength.LIMITED); 

     // assert that we're empty 
     assertFound(getSearcher1(), "test", 0); 
     assertFound(getSearcher2(), "test", 0); 

     add(this.writer1, "test"); 
     assertFound(getSearcher1(), "test", 1); 
     assertFound(getSearcher2(), "test", 1); 

     add(this.writer2, "foobar"); 
     assertFound(getSearcher1(), "foobar", 1); 
     assertFound(getSearcher2(), "foobar", 1); 
    } 

    public void assertFound(IndexSearcher searcher, String q, int expected_number) { 
     try { 
      QueryParser parser = new QueryParser("name", new StandardAnalyzer()); 
      Query query = parser.parse(q); 
      TopDocs t = searcher.search(query, null, 50); 
      assertEquals(expected_number, t.totalHits); 
     } catch (Exception e) { 
      e.printStackTrace(); 
      fail(); 
     } 

    } 

    public IndexSearcher getSearcher1() throws CorruptIndexException, IOException { 
     if (this.searcher1 == null) { 
      this.searcher1 = new IndexSearcher(IndexReader.open(this.directory1)); 
     } else { 
      IndexReader new_reader, old_reader; 

      old_reader = this.searcher1.getIndexReader(); 
      new_reader = old_reader.reopen(); 

      if (new_reader != old_reader) { 
       System.err.println("index1 changed"); 
       this.searcher1.close(); 
       old_reader.close(); 
       this.searcher1 = new IndexSearcher(new_reader); 
      } 
     } 

     return this.searcher1; 
    } 

    public IndexSearcher getSearcher2() throws CorruptIndexException, IOException { 
     if (this.searcher2 == null) { 
      this.searcher2 = new IndexSearcher(this.directory2); 
     } else { 
      IndexReader new_reader, old_reader; 

      old_reader = this.searcher2.getIndexReader(); 
      new_reader = old_reader.reopen(); 

      if (new_reader != old_reader) { 
       System.err.println("index2 changed"); 
       this.searcher2.close(); 
       old_reader.close(); 
       this.searcher2 = new IndexSearcher(new_reader); 
      } 
     } 

     return this.searcher2; 
    } 

    public void add(IndexWriter writer, String name) throws CorruptIndexException, IOException { 
     Document d = new Document(); 
     d.add(new Field("name", name, Field.Store.YES, Field.Index.ANALYZED)); 
     writer.addDocument(d); 
     writer.commit(); 
     IndexWriter.unlock(writer.getDirectory()); 
    } 
} 

我,而不是重新打开()调用使用

new_reader = IndexReader.open(this.directory1); 

测试走向绿色。

难道我错过任何重要点

看到的IndexWriter#解锁的javadoc:

/** 
    * Forcibly unlocks the index in the named directory. 
    * <P> 
    * Caution: this should only be used by failure recovery code, 
    * when it is known that no other process nor thread is in fact 
    * currently accessing this index. 
    */ 

我不会用,对于正常运营。

相反,打开一个新的作家并关闭它。这将正常工作 - 尽管最好只使用一个IndexWriter。

+0

ahhhhhh yesss :)现在有效。继承人谁更新和工作代码的关心: http://gist.github.com/173978 – 2009-08-25 08:34:14