Lucene系列-近实时搜索(1)
近实时搜索(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)的更多相关文章
- 【Lucene】近实时搜索
近实时搜索:可以使用一个打开的IndexWriter快速搜索索引的变更内容,而不必首先关闭writer,或者向该writer提交:这是2.9版本之后推出的新功能. 代码示例(本例参考<Lucen ...
- 剖析Elasticsearch集群系列之三:近实时搜索、深层分页问题和搜索相关性权衡之道
转载:http://www.infoq.com/cn/articles/anatomy-of-an-elasticsearch-cluster-part03 近实时搜索 虽然Elasticsearch ...
- Lucene.net 实现近实时搜索(NRT)和增量索引
Lucene做站内搜索的时候经常会遇到实时搜索的应用场景,比如用户搜索的功能.实现实时搜索,最普通的做法是,添加新的document之后,调用 IndexWriter 的 Commit 方法把内存中的 ...
- lucene4.5近实时搜索
近实时搜索就是他能打开一个IndexWriter快速搜索索引变更的内容,而不必关闭writer,或者向writer提交,这个功能是在2.9版本以后引入的,在以前没有这个功能时,必须调用writer的c ...
- lucene4之后的近实时搜索实现
好久没干这块东西了,近几天须要做这个.所以又一次学了一下.首先很感谢孔浩老师,没孔浩老师的视频我也不会进入lucene的殿堂. 老师当时讲的实时搜索还是NRTManager,如今已经都变了,这个类已经 ...
- solr 近实时搜索
摘要: Solr的近实时搜索NRT(Near Real Time Searching)意味着文档可以在索引以后马上可以被查询到. Solr不会因为本次提交而阻塞更新操作,不会等待后台合并操作(merg ...
- Solr -- 实时搜索
在solr中,实时搜索有3种方案 ①soft commit,这其实是近实时搜索,不能完全实时. ②RealTimeGet,这是实时,但只支持根据文档ID的查询. ③和第一种类似,只是触发softcom ...
- 【Lucene3.6.2入门系列】第03节_简述Lucene中常见的搜索功能
package com.jadyer.lucene; import java.io.File; import java.io.IOException; import java.text.SimpleD ...
- 关于lucene的IndexSearcher单实例,对于索引的实时搜索
Lucene版本:3.0 一般情况下,lucene的IndexSearcher都要写成单实例,因为每次创建IndexSearcher对象的时候,它都需要把索引文件加载进来,如果访问量比较大,而索引也比 ...
随机推荐
- 【C#】Excel做的数据表、SQLParameter代码生成工具
转载请注明出处http://www.cnblogs.com/Vulpers/ 做了一个小的代码生成工具,用于新建数据表时能够快速生成一些重复性很高的代码,目前仅支持SqlServer数据库及C#语言, ...
- 删除所选项(附加搜索部分的jquery)
1.视图端(views)的配置为: <script> $(document).ready(function() { $("#info-grid").kendoGrid( ...
- HTML 学习记录
<h1>This is a heading </h1> 标题 h后面的数字是字体大小 <p>This is a paragraph.</p>段落 < ...
- js execCommand
JavaScript中的execCommand()命令详解及实例展示 标签: javascriptbuttonfunctioninputobjectdelete 2012-05-07 16:08 14 ...
- Stack Overflow is a question and answer site
http://stackoverflow.com/ _ Stack Overflow is a question and answer site for professional and enthus ...
- access查询优化
一个zirancun 14万数据量,一个 zirancuntd 19万数据,这两个 zirancuntd.distid 与zirancun.id进行关联,查询 zirancuntd.distid不存 ...
- CodeBlock 使用TextOut出错
undefined reference to `TextOutA@20'C:\Program Files (x86)\CodeBlocks\MinGW\lib这次需要的库是:libgdi32.a 1. ...
- TCL:读取表格(xls)中的数据
intToChar.tcl # input a number : 1 to 32 , you will get a char A to Z #A-Z:1-32 proc intToChar {int} ...
- window.showModalDialog返回值和window.open返回值实例详解
最近在谷歌浏览器下发现一个问题,就是使用谷歌浏览器已经不兼容window.showModalDialog了,所以还是改成使用window.open(). 一.window.showModalDialo ...
- Android PullToZoomListView实现放大回弹效果
另外一个相同项目的地址https://github.com/Frank-Zhu/PullZoomView 转自http://blog.csdn.net/wangjinyu501/article/det ...