Lucene IndexReader.reopen似乎无法正常工作

时间:2009-08-24 17:50:23

标签: java lucene

我遇到Lucene 2.4的问题,情况如下:

我必须处理在同一个Index目录上运行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());
    }
}

当我而不是reopen()调用时使用

new_reader = IndexReader.open(this.directory1);

测试变绿了。

我是否遗漏了任何重要的观点

1 个答案:

答案 0 :(得分:2)

请参阅IndexWriter#unlock 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。

相关问题