设为首页 收藏本站
查看: 498|回复: 0

[经验分享] Apache Lucene3.0 入门实例介绍

[复制链接]

尚未签到

发表于 2017-1-7 10:47:37 | 显示全部楼层 |阅读模式
  咱这搞技术活儿的吧,得会用Google/Baidu!
  这哥俩儿在我们的成长过程中,起着举足轻重的作用,马大队长(马士兵)时刻提醒我们有不懂的首先问问Google/Baidu。输入我们感兴趣的话题直接回车就可以获取到互联网上所有的信息,那么多的信息量,却在毫秒级的时间里返回,不无感慨一下它的强大。当然,搜索之属于产生正是由于互联网越来越庞大的信息量。
  一应用系统,随着时间的推移,数据量越来越大,系统性能是否经受得住考验?!这是个我们必须考虑的问题。我们知道,通过SQL的like模糊查询数据匹配时是巨慢的,我想你肯定有收到过用户为系统的低效而抱怨的信息,你优化SQL还是达不到预想的速度,基于此,我们有必要研究一下搜索引擎。
  lucene是一个高性能的、可扩展的信息检索工具库。我们可以把它融入到我们所开发的应用程序中来增加索引和搜索功能。
  说说索引和搜索的关系吧:
  索引操作是所有搜索引擎的核心概念:为了进行快速查找,就需要把数据处理成一种高效的、可交叉引用的查找表格式。
  我们知道,为了提高数据库的数据检索性能,我们通常会对相应的列做索引,然后通过搜索找到相应的索引,再通过索引找到相对应的数据,这样查询速度会提高很多。实际上,我们仔细思考这一种策略,确实是有一定的道理的。
  搜索是一个在索引中查找关键字的过程。你原来需要在巨多的数据中搜索你想要的数据,现在只要在你建立的少量索引文件中检索,这高效不言而喻。
  越来越有点意思了对吧,所以,Lucene应用实例,Come on(以下代码示例均来自Lucene in action):
  创建索引文件(对扩展名为txt的文件进行索引),示例代码如下:

private IndexWriter writer;
/**
* 指定索引目录的构造函数
* */
public Indexer(String indexDir) throws IOException{
Directory dir = FSDirectory.open(new File(indexDir));
writer = new IndexWriter(dir,new StandardAnalyzer(Version.LUCENE_30),
true,
IndexWriter.MaxFieldLength.UNLIMITED);//1)
}
//关闭IndexWriter
public void close() throws CorruptIndexException, IOException{
if(null!=writer){
writer.close();
}
}
/**
* 索引
* @param dataDir 指定需要索引的数据路径
* @param filter 进行索引的文件类型
* @return int 索引的文件数
* */
public int index(String dataDir,FileFilter filter) throws IOException{
File[] files = new File(dataDir).listFiles();
for(File f:files){
if(f.isDirectory()){
index(f.getAbsolutePath(),filter);
}else if(!f.isHidden()&&
f.exists()&&
f.canRead()&&(filter==null||filter.accept(f))){
indexFile(f);
}
}
return writer.numRamDocs();//Return number of documents indexed
}
/**
* 索引指定的文件
* */
private void indexFile(File f) throws IOException{
System.out.println("Indexing "+f.getCanonicalPath());
Document doc = getDocument(f);
writer.addDocument(doc);//Add document to Lucene index
}
/**
* 指定可索引的文件类型(只索引后缀名为.txt文件)
* */
private static class TextFilesFilter implements FileFilter{
public boolean accept(File path){
return path.getName().toLowerCase().endsWith(".txt");//Index .txt files only,using FileFilter
}
}
/**
* 返回代表索引集合的文档
* */
protected Document getDocument(File f) throws IOException{
Document doc = new Document();//2)
doc.add(new Field("contents",new FileReader(f)));//Index file content(not store)
doc.add(new Field("filename",f.getName(),
Field.Store.YES,Field.Index.NOT_ANALYZED));//Index filename
doc.add(new Field("fullpath",f.getCanonicalPath(),
Field.Store.YES,Field.Index.NOT_ANALYZED));//Index file full path
return doc;
}
  现对上段代码的主要部分进行简单的说明如下:
  1)初始化IndexWriter。IndexWriter是索引过程中的核心组件,该类用于创建一个新的索引或者打开一个已经存在的,并增加、删除或更新文档中的索引。因为你要有存储索引的地方啊,所以参数需要一个存储索引的目录。该参数目录通过

Directory dir = FSDirectory.open(new File(indexDir));
  返回。org.apache.lucene.store.Directory有两个直接子类:FSDirectory和RAMDirectory。分别代表硬盘目录以及内存目录,这两个具体的含义以后再说,因为我们需要索引的文件存储在硬盘上,所以使用FSDirectory返回代表目录的实例。
  2)实例化一个Document对象,该对象代表了一些域(Field)的集合。每个域都对应一段可能在搜索过程中被查询的数据。Lucene只能处理java.lang.String、java.io.Reader以及一些基本数据类型(如int或者float)。如果要处理其它诸如Microsoft的word、excel或者html、PDF等文件类型时,则需要使用到一些其它的分析器来进行索引操作,而不只是我们上文提到的最基础的StandardAnalyzer。
  索引搜索,代码示例如下:

public static void search(String indexDir,String q)
throws IOException, ParseException{
Directory dir = FSDirectory.open(new File(indexDir));//Open index
IndexSearcher is = new IndexSearcher(dir);
QueryParser parser = new QueryParser(Version.LUCENE_30,//Parse query
"contents",
new StandardAnalyzer(
Version.LUCENE_30));
Query query = parser.parse(q);//Search index
long start = System.currentTimeMillis();
TopDocs hits = is.search(query,10);
long end = System.currentTimeMillis();
System.err.println("Found "+hits.totalHits+//Write search stats
" document(s) (in "+(end-start)+
" milliseconds) that matched query '"+
q+"':");
//Note that the TopDocs object contains only references to the underlying documents.
//In other words, instead of being loaded immediately upon search, matches are loaded
//from the index in a lazy fashion—only when requested with the Index-
//Searcher.doc(int) call.
//换言之,搜索并不立即加载,当调用IndexSearcher.doc(int)时返回。
//That call returns a Document object from which we can then
//retrieve individual field values.
for(ScoreDoc scoreDoc:hits.scoreDocs){
Document doc = is.doc(scoreDoc.doc);//Retrieve matching document
System.out.println(doc.get("fullpath"));//Display filename
System.out.println(doc.get("filename"));
System.out.println(doc.get("contents"));
}
is.close();//Close IndexerSearcher
}
  在搜索索引之前,我们必须得知道索引在哪儿吧,所以通过

Directory dir = FSDirectory.open(new File(indexDir));//Open index
  
打开索引。然后实例化IndexSearcher对象,通过QueryParser对象解析查询字符并返回一个Query对象。再调用

TopDocs hits = is.search(query,10);
  查询前10的文件集合。最后循环获取,非常的简单易懂。
  具体的输出结果我就不再浪费时间打字了,源码可参见附件。
  当然了,这只是对所有的文本文件做了一个Lucene的简单入门介绍,希望对有兴趣学习lucene的朋友提供一个入门介绍!如有不足的地方,望指出大家共同学习和进步! DSC0000.gif

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-325027-1-1.html 上篇帖子: Apache ODE 流程编译过程解析 下篇帖子: 详解Apache下.htaccess文件常用配置
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表