lucene4.5近实时搜索

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


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

import junit.framework.TestCase;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.FieldType;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.*;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.RAMDirectory;
import org.apache.lucene.util.Version;


public class NearRealTimeTest extends TestCase {
  public void testNearRealTime() throws Exception {
    Directory dir = new RAMDirectory();
    IndexWriterConfig config =  new IndexWriterConfig(Version.LUCENE_45,new StandardAnalyzer(Version.LUCENE_45));
    IndexWriter writer = new IndexWriter(dir, config);
      FieldType fieldType = new FieldType();
      fieldType.setIndexed(false);//set 是否索引
      fieldType.setStored(false);//set 是否存储
      fieldType.setTokenized(true);//set 是否分类
      fieldType.setOmitNorms(false);
    for(int i=0;i<10;i++) {
      Document doc = new Document();
      doc.add(new Field("id", ""+i, fieldType));
      doc.add(new Field("test", "aaa", TextField.TYPE_NOT_STORED));
      writer.addDocument(doc);
    }
    //IndexReader reader = writer.getReader();                 // 老版本的  3.x
    DirectoryReader reader = DirectoryReader.open(writer,true);   //创建近实时reader
    IndexSearcher searcher = new IndexSearcher(reader);   //将reader封装在IndexSearcher

    Query query = new TermQuery(new Term("test", "aaa"));
    TopDocs docs = searcher.search(query, 1);
    assertEquals(10, docs.totalHits);                        // 返回10个搜索结果

    writer.deleteDocuments(new Term("id", "7"));             // 删除一个文档

    Document doc = new Document();

    doc.add(new Field("id", "11",  fieldType));
    doc.add(new Field("test", "bbb",  TextField.TYPE_NOT_STORED));
    writer.addDocument(doc);
    
    //IndexReader newReader = reader.reopen();                 //老版本3.x
    IndexReader newReader = DirectoryReader.openIfChanged(reader,writer,true);   //重启reader
    reader.close();
    assertFalse(reader == newReader);
    reader.close();
    searcher = new IndexSearcher(newReader);

    TopDocs hits = searcher.search(query, 10);
    assertEquals(9, hits.totalHits);

    query = new TermQuery(new Term("text", "bbb"));
    hits = searcher.search(query, 1);
    assertEquals(1, hits.totalHits);

    newReader.close();
    writer.close();
  }
}

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

最后测试通过

lucene4.5近实时搜索_第1张图片


你可能感兴趣的:(lucene4.5近实时搜索)