`
javapolo
  • 浏览: 131566 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Lucene with NRTManager

阅读更多

lucene3.5 近实时搜索(Near Real Time)

最近一直再看lucene文档,发现网上对NRTManager资料很少,只有google的时候搜到几篇文章,自己结合一些官方文档和一些资料,稍稍做了个笔记,以备后用

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对象来获取最新索引

 

分享到:
评论
4 楼 乐文雍 2012-09-10  
这种方式貌似也只适合于index和search在同一个JVM中的情况啊!
3 楼 javapolo 2012-05-27  
huangfoxAgain 写道
请问你有类似实例么?以前都是通过从indexWriter中获取indexreader,然后构建indexSearcher实现nrt,虽然不用commit、reopen即可完成indexSearcher及时可见更新,但是在删除 合并环节有问题。特别是在3.5对optimize方法过时后,我才关注了nrtManager。
希望多和博主交流、学习。

zjxux 写道
NRTManager, 这个不太会用,求教使用方法?

最近一直在做项目所以没上javaeye,你们可以先参考http://blog.mikemccandless.com/2011/11/near-real-time-readers-with-lucenes.html这篇文档,然后看下面的demo
package oa002.util;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executors;

import oa002.dto.DocumentVo;
import oa002.dto.SearcherResVo;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.Field.Index;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.queryParser.MultiFieldQueryParser;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.NRTManager;
import org.apache.lucene.search.NRTManagerReopenThread;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.SearcherManager;
import org.apache.lucene.search.SearcherWarmer;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.search.highlight.Highlighter;
import org.apache.lucene.search.highlight.InvalidTokenOffsetsException;
import org.apache.lucene.search.highlight.QueryScorer;
import org.apache.lucene.search.highlight.SimpleFragmenter;
import org.apache.lucene.search.highlight.SimpleHTMLFormatter;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.store.LockObtainFailedException;
import org.apache.lucene.util.Version;
import org.apache.tika.Tika;
import org.apache.tika.exception.TikaException;

import com.chenlb.mmseg4j.analysis.MMSegAnalyzer;

/**
* 通过它来对索引做直接的操作
*
* @author Administrator
*
*/
public class LuceneUtil {
// 近实时搜索管理器
public static NRTManager nrtManager;
// 索引的写工具
public static IndexWriter indexWriter;
// 分词器
public static Analyzer analyzer;
// 索引目录对象
public static Directory dir;
// 索引的路径
public static String INDEX_PATH;
// 字典的路径
public static String DICTIONARY_PATH;
// 近实时搜索的线程
public static NRTManagerReopenThread thread;

/**
* 单例模式获取nrtmanager对象
*
* @return
*/
public static NRTManager getNrtManager() {
if (nrtManager == null) {
try {
analyzer = new MMSegAnalyzer(new File(DICTIONARY_PATH));
dir = FSDirectory.open(new File(INDEX_PATH));
IndexWriterConfig config = new IndexWriterConfig(
Version.LUCENE_35, analyzer);
indexWriter = new IndexWriter(dir, config);
nrtManager = new NRTManager(indexWriter,
Executors.newCachedThreadPool(), new SearcherWarmer() {
@Override
public void warm(IndexSearcher arg0)
throws IOException {

System.out.println("it  has  changed!!!");

}
});
double minStaleSec = 0.025;
double maxStaleSec = 5.0;
thread = new NRTManagerReopenThread(nrtManager, maxStaleSec,
minStaleSec);
thread.setDaemon(true);
thread.start();

} catch (CorruptIndexException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (LockObtainFailedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return nrtManager;
}

/**
* 初始化路径
*
* @param indexpath
* @param dicpath
*/
public static void init(String indexpath, String dicpath) {
INDEX_PATH = indexpath;
DICTIONARY_PATH = dicpath;

}

/**
* 添加文件
*
* @param path
*/
public void addFile(String path, String address, String filetruename) {

try {
NRTManager manager = LuceneUtil.getNrtManager();
File file = new File(path);
Document document = new Document();
Field field = new Field("filename", filetruename, Field.Store.YES,
Index.NOT_ANALYZED);
document.add(field);
field = new Field("filecontent", new Tika().parseToString(file),
Field.Store.NO, Index.ANALYZED);
document.add(field);
field = new Field("filepath", path, Field.Store.YES, Index.NO);
document.add(field);

field = new Field("fileaddr", address, Field.Store.YES, Index.NO);
document.add(field);

manager.addDocument(document);
LuceneUtil.indexWriter.commit();

} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (TikaException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}

/**
* 根据条件查询
*
* @param conditions
* @return
*/
public SearcherResVo searcherByCondition(int currentpage, String conditions) {
SearcherResVo rs = new SearcherResVo();

List<DocumentVo> documentvos = new ArrayList<DocumentVo>();
try {
System.out.println(INDEX_PATH);
// 开始查询的系统时间
long begin = System.currentTimeMillis();
NRTManager nrtmanager = LuceneUtil.getNrtManager();
SearcherManager manager = nrtmanager.getSearcherManager(true);
System.out.println("----------------");
System.out.println(indexWriter.maxDoc());
System.out.println(indexWriter.numDocs());

IndexSearcher searcher = manager.acquire();

MultiFieldQueryParser parser = new MultiFieldQueryParser(
Version.LUCENE_35, new String[] { "filecontent", },
analyzer);

Query query = parser.parse(conditions);

System.out.println("在查询条件是" + conditions);

TopDocs docs = searcher.search(query, 100);

System.out.println("长度" + docs.scoreDocs.length);

// 设置当前页
rs.setCurrentpage(currentpage);
// 结束查询是的时间
long end = System.currentTimeMillis();
// 设置搜索时间
rs.setSearcherTime(end - begin);
// 设置总共查询到的条数
rs.setTotalresult(docs.totalHits);
// 设置总的页数
if (rs.getTotalresult() != 0
&& rs.getTotalresult() % rs.getPerpagesize() == 0)
rs.setPageTotal(rs.getTotalresult() / rs.getPerpagesize());
else {
rs.setPageTotal(rs.getTotalresult() / rs.getPerpagesize() + 1);
}
// scoreafter对应的下标
int start = (currentpage - 1) * (rs.getPerpagesize() - 1);

System.out.println("start------->" + start);

System.out.println("hits-------->" + docs.totalHits);

System.out.println("currentpage-------->" + currentpage);

// 当当前页码是1的时候,searchAfter会忽略第一个命中的元素,所以提前将其置于数组当中
if (currentpage == 1 && docs.scoreDocs.length >= 1) {
DocumentVo vo = new DocumentVo();
Document document = searcher.doc(docs.scoreDocs[0].doc);
vo.setFilename(document.get("filename"));
vo.setFileurl(document.get("filepath"));
vo.setFileaddr(document.get("fileaddr"));
System.out.println("--------------------------->"
+ document.get("fileaddr"));
vo.setFilescoredfragment(hightlightText(query, document));
documentvos.add(vo);
}
TopDocs tops = null;
if (docs.scoreDocs.length > 1) {
if (currentpage == 1)
tops = searcher.searchAfter(docs.scoreDocs[start], query,
rs.getPerpagesize() - 1);
else
tops = searcher.searchAfter(docs.scoreDocs[start], query,
rs.getPerpagesize());
}
if (tops != null)
for (ScoreDoc doc : tops.scoreDocs) {
System.out.println("i------------->");
DocumentVo vo = new DocumentVo();
Document document = searcher.doc(doc.doc);
vo.setFilename(document.get("filename"));
vo.setFileurl(document.get("filepath"));
vo.setFileaddr(document.get("fileaddr"));
vo.setFilescoredfragment(hightlightText(query, document));
documentvos.add(vo);
}
// 设置记录的详细
rs.setDocumentvos(documentvos);

} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return rs;
}

/**
* 高亮选中
*
* @param query
* @param document
* @return
*/
public String hightlightText(Query query, Document document) {
String res = null;

try {
SimpleFragmenter fragment = new SimpleFragmenter();
fragment.setFragmentSize(200);
QueryScorer queryScorer = new QueryScorer(query);
Highlighter highter = new Highlighter(new SimpleHTMLFormatter(
"<font   color='red'>", "</font>"), queryScorer);
highter.setTextFragmenter(fragment);
res = highter.getBestFragment(new MMSegAnalyzer(
LuceneUtil.DICTIONARY_PATH), "filecontent", new Tika()
.parseToString(new File(document.get("filepath"))));

} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvalidTokenOffsetsException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (TikaException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return res;

}

}
2 楼 zjxux 2012-05-15  
NRTManager, 这个不太会用,求教使用方法?
1 楼 huangfoxAgain 2012-05-14  
请问你有类似实例么?以前都是通过从indexWriter中获取indexreader,然后构建indexSearcher实现nrt,虽然不用commit、reopen即可完成indexSearcher及时可见更新,但是在删除 合并环节有问题。特别是在3.5对optimize方法过时后,我才关注了nrtManager。
希望多和博主交流、学习。

相关推荐

    NrtManager:来自 Lucene 3.5.0 的 NrtManager 和 SearcherManager 的 C# 端口

    《NrtManager与SearcherManager在C#中的应用——源自Lucene 3.5.0的移植实践》 在搜索引擎开发领域,Lucene是一个广泛使用的全文检索库,它提供了高效、可扩展的文本搜索功能。Java版本的Lucene 3.5.0引入了...

    lucene,lucene教程,lucene讲解

    lucene,lucene教程,lucene讲解。 为了对文档进行索引,Lucene 提供了五个基础的类 public class IndexWriter org.apache.lucene.index.IndexWriter public abstract class Directory org.apache.lucene.store....

    lucene3.0 lucene3.0

    lucene3.0 lucene3.0 lucene3.0 lucene3.0 lucene3.0

    lucene-4.7.0全套jar包

    【Lucene 4.7.0 全套JAR包详解】 Lucene是一个开源全文搜索引擎库,由Apache软件基金会开发并维护。它提供了一个高级、灵活的文本搜索API,允许开发者轻松地在应用程序中实现复杂的搜索功能。这次提供的“lucene-...

    Lucene3.5源码jar包

    本压缩包包含的是Lucene 3.5.0版本的全部源码,对于想要深入理解Lucene工作原理、进行二次开发或者进行搜索引擎相关研究的开发者来说,是一份非常宝贵的学习资源。 Lucene 3.5.0是Lucene的一个重要版本,它在3.x...

    Lucene时间区间搜索

    Lucene是一款强大的全文搜索引擎库,广泛应用于各种数据检索场景。在C#环境下,利用Lucene进行时间区间搜索是提高数据检索效率和精确度的重要手段。本篇将深入探讨如何在C#中实现Lucene的时间区间查询匹配,以及涉及...

    lucene in action英文版 lucene 3.30包

    《Lucene in Action》是关于Apache Lucene的权威指南,这本书深入浅出地介绍了全文搜索引擎的构建和优化。Lucene是一个高性能、全文本搜索库,它允许开发人员在应用程序中轻松实现复杂的搜索功能。这本书主要面向...

    Lucene示例 BM25相似度计算

    在IT领域,搜索引擎技术是至关重要的,而Lucene作为一个开源全文搜索引擎库,广泛应用于各种文本检索系统中。本文将深入探讨Lucene示例中的BM25相似度计算,旨在帮助初学者理解如何利用Lucene 4.7.1版本构建索引、...

    lucene-4.0.0完整包

    **Lucene 4.0.0 全文检索引擎工具包** Apache Lucene 是一个高度成熟、广泛使用的开源全文检索库,由Java编写。作为一款搜索引擎工具包,它提供了核心的索引和搜索功能,使得开发者能够快速地在应用程序中集成强大...

    Annotated Lucene 中文版 Lucene源码剖析

    《Annotated Lucene 中文版 Lucene源码剖析》是一本深入探讨Apache Lucene的书籍,专注于源码解析,帮助读者理解这个强大的全文搜索引擎库的工作原理。Lucene是一款开源的Java库,它提供了高效的文本搜索功能,被...

    Lucene简介.介绍

    【Lucene 简介】 Lucene 是一个强大的开源全文搜索库,由 Java 编写,主要用于为应用程序添加全文检索功能。它不是一个完整的全文搜索引擎应用,而是一个工具包,允许开发者将其集成到自己的软件中,以实现高效、...

    lucene 2.0 api以及lucene 3.0 api

    **Lucene 2.0 API 和 Lucene 3.0 API 深度解析** Lucene 是一个由 Apache 软件基金会开发的全文搜索引擎库,它为开发者提供了在 Java 应用程序中实现高性能、可扩展的全文搜索功能的能力。Lucene 的 API 设计得相当...

    Lucene的原理完整版pdf

    **Lucene原理详解** Lucene是一个高性能、全文检索库,由Apache软件基金会开发并维护,是Java编程语言中广泛使用的搜索引擎库。它提供了一个简单但功能强大的API,用于索引和搜索文本数据,使得开发者可以轻松地在...

    lucene所有的jar包

    《全面解析Lucene jar包:从基础到应用》 在信息技术高速发展的今天,搜索引擎已经成为我们获取信息不可或缺的工具。在Java领域,Lucene作为一个强大的全文搜索引擎库,深受开发者喜爱。本文将详细介绍“lucene所有...

    lucene in action 2nd edition, lucene in action 第二版 PDF

    《Lucene in Action 第二版》是一本深入探讨Apache Lucene全文检索库的专业书籍,它在Java开发领域具有很高的权威性。这本书详细介绍了如何利用Lucene进行高效的文本搜索和索引构建,是Java开发者和信息检索爱好者的...

    lucene-core-7.7.0-API文档-中文版.zip

    赠送jar包:lucene-core-7.7.0.jar; 赠送原API文档:lucene-core-7.7.0-javadoc.jar; 赠送源代码:lucene-core-7.7.0-sources.jar; 赠送Maven依赖信息文件:lucene-core-7.7.0.pom; 包含翻译后的API文档:lucene...

    Lucene与关系型数据库对比

    《Lucene与关系型数据库对比:深度解析与应用探索》 在信息爆炸的时代,数据管理和检索成为了企业乃至个人日常工作中不可或缺的部分。随着技术的发展,不同的数据处理方式应运而生,其中Lucene与关系型数据库作为两...

    Lucene资料大全(包括Lucene_in_Action书等)

    标题"Lucene资料大全(包括Lucene_in_Action书等)"表明这是一个包含全面Lucene学习资源的集合,其中最显著的是《Lucene_in_Action》这本书。这是一本广泛认可的关于Apache Lucene的权威指南,通常被简称为LIA,它深入...

    lucene.NET 中文分词

    **Lucene.NET 中文分词技术详解** Lucene.NET 是一个高性能、全文检索库,它是Apache Lucene项目在.NET平台上的实现。作为一个开源的搜索引擎框架,Lucene.NET为开发者提供了强大的文本搜索功能。而在处理中文文档...

Global site tag (gtag.js) - Google Analytics