我需要在添加文档后立即使用Lucene中的结果。我读到的所有内容都说我应该缓存IndexSearcher实例,但是如果没有在每次写入时重新打开IndexReader,我也不会看到如何实现我想要的,因此也是IndexSearcher ...
我做错了什么?
class LuceneStorage {
private final Directory luceneDirectory;
private final IndexWriter indexWriter;
private volatile DirectoryReader indexReader;
LuceneStorage() {
try {
this.luceneDirectory = NIOFSDirectory.open(Paths.get(System.getProperty("user.home")).resolve("lucene"));
IndexWriterConfig config = new IndexWriterConfig(new KeywordAnalyzer());
config.setOpenMode(IndexWriterConfig.OpenMode.CREATE_OR_APPEND);
this.indexWriter = new IndexWriter(luceneDirectory, config);
this.indexReader = DirectoryReader.open(indexWriter);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
public Stream<String> read(String id) {
IndexSearcher indexSearcher = new IndexSearcher(indexReader);
QueryParser queryParser = new QueryParser("id", new KeywordAnalyzer());
StreamableSimpleCollector collector = new StreamableSimpleCollector();
try {
indexSearcher.search(queryParser.parse(id), collector);
} catch (Exception e) {
throw new IllegalStateException(e);
}
IntStream docIds = collector.stream();
return docIds.mapToObj(i -> {
try {
return indexSearcher.doc(i).get("content");
} catch (IOException e) {
throw new UncheckedIOException(e);
}
});
}
public String write(String content, String... ids) {
String uuid = UUID.randomUUID().toString();
Document document = new Document();
document.add(new StringField("id", uuid, Field.Store.YES));
Stream.of(ids)
.forEach(i -> document.add(new StringField("id", i, Field.Store.YES)));
document.add(new StoredField("content", content));
try {
indexWriter.addDocument(document);
indexReader = DirectoryReader.openIfChanged(indexReader);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
return uuid;
}
}
答案 0 :(得分:0)
Lucene并非旨在提供实时搜索结果。因此,如果这确实是一项要求,那么你应该看看别的东西。
然而,Lucene可以提供近实时搜索结果,因此您的用户最多必须等待,例如。在更改之前1秒可搜索。这样做的方法是使用SearcherManager(http://lucene.apache.org/core/5_5_0/core/org/apache/lucene/search/SearcherManager.html)并有一个后台线程,定期刷新当前的索引读取器。