lucene4.5近实时搜索

近实时搜索就是他能打开一个IndexWriter快速搜索索引变更的内容,而不必关闭writer,或者向writer提交,这个功能是在2.9版本以后引入的,在以前没有这个功能时,必须调用writer的commit方法,然后重新打开reader,这个过程很耗费时间,因为writer的提交必须对索引里的所有新文件进行同步,同步操作耗费系统资源,近实时搜索使我们能够对新创建还未提交的索引进行搜索。

 

  在4.5的版本上做一个简单的测试示例,参考lucene in action

 

  1. import junit.framework.TestCase;  
  2. import org.apache.lucene.analysis.standard.StandardAnalyzer;  
  3. import org.apache.lucene.document.Document;  
  4. import org.apache.lucene.document.Field;  
  5. import org.apache.lucene.document.FieldType;  
  6. import org.apache.lucene.document.TextField;  
  7. import org.apache.lucene.index.*;  
  8. import org.apache.lucene.search.IndexSearcher;  
  9. import org.apache.lucene.search.Query;  
  10. import org.apache.lucene.search.TermQuery;  
  11. import org.apache.lucene.search.TopDocs;  
  12. import org.apache.lucene.store.Directory;  
  13. import org.apache.lucene.store.RAMDirectory;  
  14. import org.apache.lucene.util.Version;  
  15.   
  16.   
  17. public class NearRealTimeTest extends TestCase {  
  18.   public void testNearRealTime() throws Exception {  
  19.     Directory dir = new RAMDirectory();  
  20.     IndexWriterConfig config =  new IndexWriterConfig(Version.LUCENE_45,new StandardAnalyzer(Version.LUCENE_45));  
  21.     IndexWriter writer = new IndexWriter(dir, config);  
  22.       FieldType fieldType = new FieldType();  
  23.       fieldType.setIndexed(false);//set 是否索引  
  24.       fieldType.setStored(false);//set 是否存储  
  25.       fieldType.setTokenized(true);//set 是否分类  
  26.       fieldType.setOmitNorms(false);  
  27.     for(int i=0;i<10;i++) {  
  28.       Document doc = new Document();  
  29.       doc.add(new Field("id"""+i, fieldType));  
  30.       doc.add(new Field("test""aaa", TextField.TYPE_NOT_STORED));  
  31.       writer.addDocument(doc);  
  32.     }  
  33.     //IndexReader reader = writer.getReader();                 // 老版本的  3.x  
  34.     DirectoryReader reader = DirectoryReader.open(writer,true);   //创建近实时reader  
  35.     IndexSearcher searcher = new IndexSearcher(reader);   //将reader封装在IndexSearcher  
  36.   
  37.     Query query = new TermQuery(new Term("test""aaa"));  
  38.     TopDocs docs = searcher.search(query, 1);  
  39.     assertEquals(10, docs.totalHits);                        // 返回10个搜索结果  
  40.   
  41.     writer.deleteDocuments(new Term("id""7"));             // 删除一个文档  
  42.   
  43.     Document doc = new Document();  
  44.   
  45.     doc.add(new Field("id""11",  fieldType));  
  46.     doc.add(new Field("test""bbb",  TextField.TYPE_NOT_STORED));  
  47.     writer.addDocument(doc);  
  48.       
  49.     //IndexReader newReader = reader.reopen();                 //老版本3.x  
  50.     IndexReader newReader = DirectoryReader.openIfChanged(reader,writer,true);   //重启reader  
  51.     reader.close();  
  52.     assertFalse(reader == newReader);  
  53.     reader.close();  
  54.     searcher = new IndexSearcher(newReader);  
  55.   
  56.     TopDocs hits = searcher.search(query, 10);  
  57.     assertEquals(9, hits.totalHits);  
  58.   
  59.     query = new TermQuery(new Term("text""bbb"));  
  60.     hits = searcher.search(query, 1);  
  61.     assertEquals(1, hits.totalHits);  
  62.   
  63.     newReader.close();  
  64.     writer.close();  
  65.   }  
  66. }  

可以看到更新文档后用 DirctoryReader.openIfChanged来获取Reader,如果有新内容,则返回新的Reader,这时我们需要关闭老的Reader。

 

最后测试通过

原文地址:https://www.cnblogs.com/zhwl/p/3499557.html