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

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

最后测试通过

上一篇:【Java】XML解析之DOM


下一篇:go子串查询,子串统计,开始和结尾判断