全部。
我是 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 控制器。在“创建”方法中,我试图在创建 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);
}
}
}
有什么建议么?谢谢你。