近实时搜索(near-real-time)可以搜索IndexWriter还未commit的内容,介于immediate和eventual之间,在数据比较大、更新较频繁的情况下使用。本文主要来介绍下如何使用,其原理还没弄透,改天再续。本文代码基于lucene 4.10

IndexReader的重建

想要看到新的结果就需要重新打开一个IndexReader,DirectoryReader提供了DirectoryReader openIfChanged(DirectoryReader oldReader)函数,只有索引有变化时才建立新reader(不是完全打开一个new reader,会复用old reader的一些资源,并入新索引,降低一些开销), 否则返回oldReader。

IndexWriter writer = new IndexWriter(ramDir, writerConfig);
//IndexReader,基于IndexWriter打开的IndexReader
IndexReader reader = DirectoryReader.open(writer, true);
IndexSearcher searcher = new IndexSearcher(reader);
//update index
//openIfChanged,如果有提交或未提交的变化,就打开新的indexreader。记住关闭old reader
IndexReader newReader = DirectoryReader.openIfChanged((DirectoryReader) reader, writer, true);
if (reader != newReader) {
searcher = new IndexSearcher(newReader);
reader.close();
}

使用过程:DirectoryReader尝试打开新IndexReader;判断是否获得新Reader;如果成功,关闭老reader。


SearchManager

在实际应用中,会并行的进行搜索、建索引、打开新Reader、关闭老reader,操作比较复杂还有线程安全问题。为了简化使用流程,lucene提供了SearcherManager extends ReferenceManager<IndexSearcher>管理IndexReader的重建和关闭,保证了线程安全,封装了IndexSearcher的生成。主要提供如下三个接口:

  • acquire获取当前已打开的最新IndexSearcher
  • release释放不用的引用,本质调的是IndexReader.close(),当一个IndexReader内部的引用计数为0时,会关闭自己释放资源。
  • maybeRefresh,尝试打开新的IndexReader,本质调用的是DirectoryReader.openIfChanged
ReferenceManager<IndexSearcher> searcherManager = new SearcherManager(writer, true, new SearcherFactory());
SearchersearcherManager.maybeRefresh()
IndexSearcher searcher = searcherManager.acquire();
//after using,释放掉
searcherManager.release(searcher);
searcherManager.close();


ControlledRealTimeReopenThread

如上,如果想获得最新的searcher,就需要周期性的调用maybeRefresh来更新searcher引用。Lucene提供了ControlledRealTimeReopenThread线程工具类来负责周期性的打开ReferenceManager(调用ReferenceManager.maybeRefresh)。该线程类控制打开间隔比较灵活,当有外部用户在等待重新打开Searcher时就按最小时间间隔等待,如果没有用户着急获取新Searcher,则等待最大时间间隔后再打开。其构造函数如下:

ControlledRealTimeReopenThread(TrackingIndexWriter writer, ReferenceManager<T> manager,
double targetMaxStaleSec, double targetMinStaleSec)//单位秒

如何判断是否有人等待?

TrackingIndexWriter封装了IndexWriter,为每次更新索引的操作赋予一个标记(generation,代数),递增变化。用户使用ControlledRealTimeReopenThread.waitForGeneration告诉其期望获得更新代数,ControlledRealTimeReopenThread记录了当前已打开的代数,当期望更新代数大于已打开代数时,就表示有用户期望获得最新Search。

如果想利用TrackingIndexWriter提供的代数概念,每次使用IndexWriter都要经过TrackingIndexWriter,否则代数没意义。但是如果只希望每隔10s打开一次新searcher,并不在意某次更新快速看到,那就可以忽略TrackingIndexWriter,ControlledRealTimeReopenThread就退化为一个clock线程。

ControlledRealTimeReopenThread th = new ...;
th.start();
th.waitForGeneration(targetGen);

Lucene系列-近实时搜索(1)的更多相关文章

  1. 【Lucene】近实时搜索

    近实时搜索:可以使用一个打开的IndexWriter快速搜索索引的变更内容,而不必首先关闭writer,或者向该writer提交:这是2.9版本之后推出的新功能. 代码示例(本例参考<Lucen ...

  2. 剖析Elasticsearch集群系列之三:近实时搜索、深层分页问题和搜索相关性权衡之道

    转载:http://www.infoq.com/cn/articles/anatomy-of-an-elasticsearch-cluster-part03 近实时搜索 虽然Elasticsearch ...

  3. Lucene.net 实现近实时搜索(NRT)和增量索引

    Lucene做站内搜索的时候经常会遇到实时搜索的应用场景,比如用户搜索的功能.实现实时搜索,最普通的做法是,添加新的document之后,调用 IndexWriter 的 Commit 方法把内存中的 ...

  4. lucene4.5近实时搜索

    近实时搜索就是他能打开一个IndexWriter快速搜索索引变更的内容,而不必关闭writer,或者向writer提交,这个功能是在2.9版本以后引入的,在以前没有这个功能时,必须调用writer的c ...

  5. lucene4之后的近实时搜索实现

    好久没干这块东西了,近几天须要做这个.所以又一次学了一下.首先很感谢孔浩老师,没孔浩老师的视频我也不会进入lucene的殿堂. 老师当时讲的实时搜索还是NRTManager,如今已经都变了,这个类已经 ...

  6. solr 近实时搜索

    摘要: Solr的近实时搜索NRT(Near Real Time Searching)意味着文档可以在索引以后马上可以被查询到. Solr不会因为本次提交而阻塞更新操作,不会等待后台合并操作(merg ...

  7. Solr -- 实时搜索

    在solr中,实时搜索有3种方案 ①soft commit,这其实是近实时搜索,不能完全实时. ②RealTimeGet,这是实时,但只支持根据文档ID的查询. ③和第一种类似,只是触发softcom ...

  8. 【Lucene3.6.2入门系列】第03节_简述Lucene中常见的搜索功能

    package com.jadyer.lucene; import java.io.File; import java.io.IOException; import java.text.SimpleD ...

  9. 关于lucene的IndexSearcher单实例,对于索引的实时搜索

    Lucene版本:3.0 一般情况下,lucene的IndexSearcher都要写成单实例,因为每次创建IndexSearcher对象的时候,它都需要把索引文件加载进来,如果访问量比较大,而索引也比 ...

随机推荐

  1. Windows XP发行12周年,我正步入中年,你已垂暮

    2001年10月25日,Windows XP正式全球上市!作为Windows 2000的升级版本,XP拥有大量新的功能:新的用户界面.防火墙整合等,这些都大大的增强了系统的易用性和安全性.而微软将于2 ...

  2. angular.js中插值语法和ng-bind以及ng-model的区别

    首先呢,插值语法也就是{{}}和ng-bind基本上是没有区别的. 主要区别在于,使用花括号语法时,在AngularJS使用数据替换模板中的花括号时,第一个加载的页面,通常是应用中的index.htm ...

  3. bash快捷建

    bash快捷建 ctrl键组合ctrl+a:光标移到行首.ctrl+b:光标左移一个字母ctrl+c:杀死当前进程.ctrl+d:退出当前 Shell.ctrl+e:光标移到行尾.ctrl+h:删除光 ...

  4. Object 转化为String时的一个问题 null->"null"

    近日在工作出了一个较大的问题,导致被客户投诉. 事情大致是,某个功能里新增对用户手机的修改,在平台数据同步过程中,出现了将用户以前的要同步的数据,那时还没有手机号码所以是null,新功能上线后,将手机 ...

  5. swift 如何给tabBarItem的相关设计

    //设置tabBarItem的title,以及点击和不点击状态图片 self.tabBarController.tabBarItem = UITabBarItem(title: "投资理财& ...

  6. CodeForces 742A Arpa’s hard exam and Mehrdad’s naive cheat

    题意:求1378 n次幂的最后一位. 析:两种方法,第一种,就是快速幂,第二种找循环节,也很好找,求一下前几个数就好. 代码如下: #pragma comment(linker, "/STA ...

  7. 使用CTex完成北京科技大学本科生毕业设计

    var appInsights=window.appInsights||function(config){ function r(config){t[config]=function(){var i= ...

  8. Fix git 提交代码错误

    今天用git clone下代码,修改,push提交,发现以下错误 [root@localhost gocache]# git push origin master error: The request ...

  9. Win7 关闭Window update

    1.设置注册表关闭自动更新 按组合键“windows+r”,打开“运行”栏,输入“regedit”,打开注册表找到下面的路径HKEY_CURRENT_USER\Software\Microsoft\W ...

  10. C#交错数组

    交错数组本质上是一维数组只不过这个一维数组里的元素都是数组.因为该一维数组里面的元素可以是任何大小的数组所以定义时只能以这样的格式定义 ][]; 定义完后必须对该数组进行初始化后方可进行赋值等操作否则 ...