1

全て。

私は lucene の初心者で、spring-mvc (3.2.5.RELEASE) と lucene(4.6.0) を使用しています。どちらも現在最新バージョンです。NEAR REAL TIME 検索を使用するにはどうすればよいですか?

このコードを書いて、IndexWriter (sington) のインスタンスを取得します

package com.github.yingzhuo.mycar.search;

import java.io.IOException;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.core.io.Resource;
import org.springframework.util.Assert;
import org.wltea.analyzer.lucene.IKAnalyzer;

public class IndexWriterFactoryBean implements FactoryBean<IndexWriter>, InitializingBean, DisposableBean {

    private static final Logger LOGGER = LoggerFactory.getLogger(IndexWriterFactoryBean.class);

    private Analyzer analyzer = new IKAnalyzer(false);
    private Resource indexDirectory = null;
    private IndexWriter indexWriter = null;
    private Directory directory = null;

    public IndexWriterFactoryBean() {
        if (indexDirectory != null) {
            try {
                if (! indexDirectory.getFile().exists()) {
                    FileUtils.forceMkdir(indexDirectory.getFile());
                }
            } catch (IOException e) {
                LOGGER.warn(e.getMessage(), e);
            }
        }
    }

    @Override
    public IndexWriter getObject() throws Exception {
        return indexWriter;
    }

    @Override
    public Class<?> getObjectType() {
        return IndexWriter.class;
    }

    @Override
    public boolean isSingleton() {
        return true;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        Assert.notNull(analyzer, "property 'analyzer' must be set.");
        Assert.notNull(indexDirectory, "property 'indexDirectory' must be set.");

        directory = FSDirectory.open(indexDirectory.getFile());
        indexWriter = new IndexWriter(directory, new IndexWriterConfig(Version.LUCENE_46, analyzer));
    }

    @Override
    public void destroy() throws Exception {
        IOUtils.closeQuietly(indexWriter);
        IOUtils.closeQuietly(directory);
        IOUtils.closeQuietly(analyzer);
    }

    // getter & setter
    // ------------------------------------------------------------------------------------------

    public void setAnalyzer(Analyzer analyzer) {
        this.analyzer = analyzer;
    }

    public void setIndexDirectory(Resource indexDirectory) {
        this.indexDirectory = indexDirectory;
    }

}

このユーティリティは、静的メソッドで DirectoryReader を取得します。

import java.io.IOException;

import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexWriter;

import com.github.yingzhuo.mycar.config.SpringUtils;

public final class DirectoryReaderHolder {

    private static DirectoryReader HOLDER = null;

    public synchronized static DirectoryReader get() {
        if (HOLDER == null) {
            try {
                HOLDER = DirectoryReader.open(SpringUtils.getBean(IndexWriter.class), true);
            } catch (IOException e) {
                throw new IllegalStateException(e);
            }
        }
        return HOLDER;
    }

    public static synchronized void set(DirectoryReader directoryReader) {
        if (directoryReader == null) {
            throw new NullPointerException();
        } else {
            HOLDER = directoryReader;
        }
    }
}

そして、この Bean を私の spring-mvc コントローラーに注入します。'create' メソッドで、IndexSearcher を作成する前に新しいリーダーを取得しようとしていますが、古いリーダーをどのように処理すればよいですか? 直接閉じることはできますか?他のスレッドがまだ古いリーダーを使用している場合、非常に悪いことが起こりますか?

package com.github.yingzhuo.mycar.search;

import java.io.IOException;

import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.search.IndexSearcher;

public class IndexSearcherManager {


    public IndexSearcher create() {
        try {
            DirectoryReader oldReader = DirectoryReaderHolder.get();
            DirectoryReader newReader = DirectoryReader.openIfChanged(oldReader);

            if (newReader != null) {
                oldReader.close();     // AM I RIGHT ???
                oldReader = newReader;
            }

            return new IndexSearcher(oldReader);
        } catch (IOException e) {
            throw new IllegalStateException(e);
        }
    }

}

助言がありますか?ありがとうございました。

4

0 に答える 0