近实时:2.9以前的版本,如果索引更新,那么搜索必须在writer的commit提交之后才能重新打开,近实时可以使得快速搜索索引的变更内容,而不必首先关闭writer或向writer提交
import java.nio.file.Paths;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.*;
import org.apache.lucene.document.Field.Store;
import org.apache.lucene.index.*;
import org.apache.lucene.search.*;
import org.apache.lucene.store.*;
import junit.framework.TestCase;
public class NearRealTimeTest extends TestCase{
public static void main(String[] args) throws Exception{
testNearRealTime();
}
public static void testNearRealTime() throws Exception{
Directory dir = FSDirectory.open(Paths.get("G:\\luceneout"));
IndexWriterConfig config = new IndexWriterConfig(new StandardAnalyzer());
IndexWriter writer = new IndexWriter(dir,config);
for(int i = 0;i < 10;i++){
Document doc = new Document();
doc.add(new StringField("id",""+i,Store.YES));
doc.add(new TextField("text","aaa",Field.Store.YES));
writer.addDocument(doc);
}
DirectoryReader reader = DirectoryReader.open(writer,true);//创建近时时reader
//该方法会将缓存中的所有变更刷新到索引目录,然后创建一个包括这些变更的IndexReader
IndexSearcher searcher = new IndexSearcher(reader);
Query query = new TermQuery(new Term("text","aaa"));
TopDocs docs = searcher.search(query, 3);
assertEquals(10,docs.totalHits);
for(ScoreDoc scoreDoc:docs.scoreDocs){
Explanation explanation = searcher.explain(query, scoreDoc.doc);//解释评分机制
System.out.print("序号为:"+scoreDoc.doc);
System.out.print("评分为:"+scoreDoc.score);
Document document = searcher.doc(scoreDoc.doc);
System.out.print("id:"+document.get("id"));
System.out.print("text:"+document.get("text"));
System.out.println(explanation.toString());//打印评分机制
System.out.println();
}
writer.deleteDocuments(new Term("id","7"));//删除一个文档
Document doc = new Document();//添加一个文档
doc.add(new StringField("id","11",Store.NO));
doc.add(new TextField("text","bbb",Store.NO));
writer.addDocument(doc);
IndexReader newReader = DirectoryReader.openIfChanged(reader, writer, true);//重启reader获得新的变更
assertFalse(reader == newReader);//确认reader是新建的
reader.close();//关闭旧的reader
searcher = new IndexSearcher(newReader);
TopDocs hits = searcher.search(query, 10);
assertEquals(9,hits.totalHits);//查验当前的9个结果
query = new TermQuery(new Term("text","bbb"));//确认匹配的新文档
hits = searcher.search(query, 1);
for(ScoreDoc scoreDoc:hits.scoreDocs){//近实时处理后的结果
System.out.print("***序号为:"+scoreDoc.doc);
System.out.print("评分为:"+scoreDoc.score);
Document document = searcher.doc(scoreDoc.doc);
System.out.print("id:"+document.get("id"));
System.out.print("text:"+document.get("text"));
System.out.println();
}
assertEquals(1,hits.totalHits);
newReader.close();
writer.close();
}
}
近实时搜索结果以及评分解释如下图