lucene3.5通过NRTManager和SearchManager实现近实时搜索

实时搜索(近实时搜索)

完全的实时搜索:只要数据库一变动,马上要更新索引,writer.commit来操作

近实时搜索:当用户修改了信息之后,先把索引保存到内存中,然后在一个统一的时间对内存中的所有的索引进行提交操作。

reopen,NRTManager(near-real-time)

lucene通过NRTManager这个类来实现近实时搜索,所谓近实时搜索即在索引发生改变时,通过线程跟踪,在相对很短的时间反映给给用户程序的调用。

NRTManager通过管理IndexWriter对象,并将IndexWriter的一些方法(增删改)例如:

addDocument,deleteDocument等方法暴露给客户调用,它的操作全部在内存里面,所以如果你不调用IndexWriter的commit方法,通过以上的操作,

用户硬盘里面的索引库是不会变化的,所以你每次更新完索引库请记得commit掉,这样才能将变化的索引一起写到硬盘中,实现索引更新后的同步用

户每次获取最新索引 (IndexSearcher),可以通过两种方式:

第一种是通过调用NRTManagerReopenThread对象,该线程负责实时跟踪索引内存的变化,每次变化就调用maybeReopen方法,保持最新代索引,

打开一个新的IndexSearcher对象,而用户所要的IndexSearcher对象是NRTManager通过调用getSearcherManager方法获得SearcherManager对象,

然后通过SearcherManager对象获取IndexSearcher对象返回个客户使用,用户使用完之后调用SearcherManager的release释放IndexSearcher对象,最

后记得关闭 NRTManagerReopenThread;

第二种方式是不通过NRTManagerReopenThread对象,而是直接调用 NRTManager的maybeReopen方法来获取最新的IndexSearcher对象来获取最

新索引。

以下是相关代码:

  private SearcherManager mgr = null;
            private NRTManager nrtMgr = null;
            private IndexWriter writer = null;

            writer = new IndexWriter(directory,new IndexWriterConfig(Version.LUCENE_35,new StandardAnalyzer(Version.LUCENE_35)));
            nrtMgr = new NRTManager (writer,new SearcherWarmer() {
                @Override
                public void warm(IndexSearcher s) throws IOException {
                    System.out.println("reopen");
                }
            });
            //启动NRTManager的Reopen线程
            NRTManagerReopenThread reopen = new NRTManagerReopenThread(nrtMgr, 5.0,0.025);
            reopen.setDaemon(true);
            reopen.setName("NrtManager Reopen Thread");
            reopen.start();
            mgr = nrtMgr.getSearcherManager(true);

    public void delete() {
        try {
            nrtMgr.deleteDocuments (new Term("id","2"));
        } catch (CorruptIndexException e) {
            e.printStackTrace();
        } catch (LockObtainFailedException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void update() {
        try {
            /*
             * Lucene并没有提供更新,这里的更新操作其实是如下两个操作的合集
             * 先删除之后再添加
             */
            Document doc = new Document();
            doc.add(new Field("id","11",Field.Store.YES,Field.Index.NOT_ANALYZED_NO_NORMS));
            doc.add(new Field("email",emails[0],Field.Store.YES,Field.Index.NOT_ANALYZED));
            doc.add(new Field("content",contents[0],Field.Store.NO,Field.Index.ANALYZED));
            doc.add(new Field("name",names[0],Field.Store.YES,Field.Index.NOT_ANALYZED_NO_NORMS));
            nrtMgr.updateDocument (new Term("id","1"), doc);
        } catch (CorruptIndexException e) {
            e.printStackTrace();
        } catch (LockObtainFailedException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void search02() {
        IndexSearcher searcher = mgr.acquire();
        try {
//            mgr.maybeReopen();//判断是否需要重新打开一个searcher
            TermQuery query = new TermQuery(new Term("content","like"));
            TopDocs tds = searcher.search(query, 10);
            for(ScoreDoc sd:tds.scoreDocs) {
                Document doc = searcher.doc(sd.doc);
                System.out.println(doc.get("id")+"---->"+
                        doc.get("name")+"["+doc.get("email")+"]-->"+doc.get("id")+","+
                        doc.get("attach")+","+doc.get("date"));
            }
        } catch (CorruptIndexException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                mgr.release(searcher);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
时间: 2024-08-26 14:35:55

lucene3.5通过NRTManager和SearchManager实现近实时搜索的相关文章

Lucene实现SearchManager近实时搜索

lucene通过NRTManager这个类来实现近实时搜索,所谓近实时搜索即在索引发生改变时,通 过线程跟踪,在相对很短的时间反映给给用户程序的调用 NRTManager通过管理IndexWriter对象,并将IndexWriter的一些方法(增删改)例如 addDocument,deleteDocument等方法暴露给客户调用,它的操作全部在内存里面,所以如果 你不调用IndexWriter的commit方法,通过以上的操作,用户硬盘里面的索引库是不会变化的,所 以你每次更新完索引库请记得co

lucene4之后的近实时搜索实现

好久没干这块东西了,近几天需要做这个,所以重新学了一下,首先非常感谢孔浩老师,没孔浩老师的视频我也不会进入lucene的殿堂. 老师当时讲的实时搜索还是NRTManager,现在已经都变了,这个类已经不存在了,在4.0之后消失的,到我现在使用的5.2.1都是下面的方法: 首先罗列会使用的特殊类(常用的不再赘述): TrackingIndexWriter  追踪writer,在api中有介绍,只有通过这个类进行更新ControlledRealTimeReopenThread才能获得更新 Contr

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

转载:http://www.infoq.com/cn/articles/anatomy-of-an-elasticsearch-cluster-part03 近实时搜索 虽然Elasticsearch中的变更不能立即可见,它还是提供了一个近实时的搜索引擎.如前一篇中所述,提交Lucene的变更到磁盘是一个代价昂贵的操作.为了避免在文档对查询依然有效的时候,提交变更到磁盘,Elasticsearch在内存缓冲和磁盘之间提供了一个文件系统缓存.内存缓存(默认情况下)每1秒刷新一次,在文件系统缓存中使

solr 近实时搜索

摘要: Solr的近实时搜索NRT(Near Real Time Searching)意味着文档可以在索引以后马上可以被查询到. Solr不会因为本次提交而阻塞更新操作,不会等待后台合并操作(merge)的完成而是直接检索索引并返回数据.参见原文 利用NRT,就可以设置soft commit,因为标准的commit操作代价高昂,soft commit可以做到近乎实时的查询效果而不丢失数据. Commits 与 Optimizing 一个commit操作可以使新的查询请求能够感知到索引的变化,一般

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

Lucene做站内搜索的时候经常会遇到实时搜索的应用场景,比如用户搜索的功能.实现实时搜索,最普通的做法是,添加新的document之后,调用 IndexWriter 的 Commit 方法把内存中的索引提交到硬盘:然后重新打开IndexReader,进行搜索.但是索引一般存储在硬盘上,而且当索引文件比较大的时候,Commit操作和重新打开IndexReader效率比较低. 于是就想,可否一份索引的IndexWriter始终打开,当需要添加或删除Document时,直接调用该IndexWrite

基于Lucene的近实时搜索引擎优化总结

一.搜索优化: 在工程领域,越是看起来“简单.确定”的问题,越是难以解决.近实时搜索引擎需要解决的问题只有一个:性能!它包含快速索引,快速搜索,以及索引到搜索的快速生效. 以下为百万条数据级(适用于千万级)快速滚动数据近实时搜索引擎实践经验总结:  1. 针对技术优化 1.1 数值搜索优化: 将数值的范围缩小,能用 int值 的不要用 long值,能用 float值 的不用要 double值:能用string 替换的,就不要用范围查询(特别是大范围查询),这些都基于Lucene搜索引擎对数值建索

一步一步跟我学习lucene(19)---lucene增量更新和NRT(near-real-time)Query近实时查询

这两天加班,不能兼顾博客的更新,请大家见谅. 有时候我们创建完索引之后,数据源可能有更新的内容,而我们又想像数据库那样能直接体现在查询中,这里就是我们所说的增量索引.对于这样的需求我们怎么来实现呢?lucene内部是没有提供这种增量索引的实现的: 这里我们一般可能会想到,将之前的索引全部删除,然后进行索引的重建.对于这种做法,如果数据源的条数不是特别大的情况下倒还可以,如果数据源的条数特别大的话,势必会造成查询数据耗时,同时索引的构建也是比较耗时的,几相叠加,势必可能造成查询的时候数据缺失的情况

使用HLS协议连接nginx实现近实时流方式播放视频

目录 1. 流媒体 1.1 流式传输 2. 点播 2.1 点播方案 2.2 什么是HLS 3. 视频编码 3.1 视频编码格式 3.2 FFmpeg 的基本使用 3.3 生成m3u8/ts文件 3.4 码率的设置 4. 播放器 4.1 技术选型 4.2 video.js 5. 开始配置nginx 6. 编写测试页面video.html 7. 测试 demo 地址 1. 流媒体 流媒体就是将视频文件分成许多小块儿,将这些小块儿作为数据包通过网络发送出去,实现一边传输视 频 数据 包一边观看视频.

SPHINX 增量索引 实现近实时更新

一.sphinx增量索引的设置   数据库中的已有数据很大,又不断有新数据加入到数据库中,也希望能够检索到.全部重新建立索引很消耗资源,因为我们需要更新的数据相比较而言很少.例如.原来的数据有几百万条,而新增的只是几千条.这样就可以使用“主索引+增量索引”的模式来实现近乎实时更新的功能. 这个模式实现的基本原理是设置两个数据源和两个索引,为那些基本不更新的数据建立主索引,而对于那些新 增的数据建立增量索引.主索引的更新频率可以设置的长一些(例如设置在每天的午夜进行),而增量索引的更新频率,我们可