lucene高级版本中添加了对实时索引查询的功能,因为在真实的应用场景中经常会对IndexWriter做写,更新或者删除操作之后马上去做查询操作,之前较低的版本中必要执行commit操作后将索引都写到磁盘之后才能从IndexSearcher 对象上的查询才能更新,老方式比较耗时。
实例代码如下:
public class LuceneNrtTest extends TestCase { public static Analyzer analyzer; static { analyzer = new StandardAnalyzer(Version.LUCENE_31); } public void testNearRealTime() throws Exception { Directory dir = new RAMDirectory(); IndexWriterConfig iwc = new IndexWriterConfig(Version.LUCENE_31, analyzer); iwc.setOpenMode(OpenMode.CREATE_OR_APPEND); IndexWriter writer = new IndexWriter(dir, iwc); for (int i = 0; i < 10; i++) { Document doc = new Document(); doc.add(new Field("id", "" + i, Field.Store.NO, Field.Index.NOT_ANALYZED_NO_NORMS)); doc.add(new Field("text", "aaa", Field.Store.NO, Field.Index.ANALYZED)); writer.addDocument(doc); } // 测试是否能查询到刚刚插入的数据 IndexReader reader = IndexReader.open(writer, false); IndexSearcher searcher = new IndexSearcher(reader); Query query = new TermQuery(new Term("text", "aaa")); TopDocs docs = searcher.search(query, 1); assertEquals(10, docs.totalHits); // 测试是否能删除一条数据 writer.deleteDocuments(new Term("id", "7")); // 再加一条 Document doc = new Document(); doc.add(new Field("id", "11", Field.Store.NO, Field.Index.NOT_ANALYZED_NO_NORMS)); doc.add(new Field("text", "bbb", Field.Store.NO, Field.Index.ANALYZED)); writer.addDocument(doc); IndexReader newReader = IndexReader.open(writer, true); 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(); } }
代码所依赖的lucene版本是:
<dependency> <groupId>org.apache.lucene</groupId> <artifactId>lucene-core</artifactId> <version>3.5.0</version> </dependency>
有一点要说明的是这里所说的实时索引,并不等同于正的实时索引,只不过接近实时索引,可能更新完条数据,马上去执行search操作,结果可能不会显示出来,要稍微等待一点时间就能查询到最新结果了(也许是十几毫秒吧),这点和数据库操作有点不一样,不过总的来说也非常好用了。