码迷,mamicode.com
首页 > Web开发 > 详细

Lucene初试

时间:2014-12-27 22:52:48      阅读:273      评论:0      收藏:0      [点我收藏+]

标签:

从知道Hadoop起就听过Lucene的大名,但是一直没有抽出时间好好学习下,最近有了段空闲时间,决定把这些东西补一下,不求知根知底,但求大致了解。

Lucene的概要描述就不多复制了,总之使用它可以快速创建索引,并进行检索,是一个设计良好的框架。

Lucene的使用十分简单,网上下载Lucene包,导入工程基本上就可以使用了,我用的是Lucene4.2的包,下载下来解压后有以下这些目录:

技术分享

简单的Lucene程序,只用引入core下面的lucene-core.jar以及analysis下面common里面的lucene-analyzers-common.jar就可以了。

Lucene设计的比较好,高级用户可以进行细致化的定制,但是如果初级用户(譬如我)使用的话,也可以很方面的使用,这里就把我的例子贴出来吧。

 1  /**
 2      * 针对某个文件夹下(不包括子文件夹)所有的txt文件建立索引,存放在该文件夹下的index文件夹中。
 3      *
 4      * @param rootPath
 5      */
 6     public static void buildIndex(String rootPath) throws IOException {
 7         //指定索引文件目录
 8         Directory indexDir = FSDirectory.open(new File(rootPath + "/index"));
 9         File dataDir = new File(rootPath);
10         File[] dataFiles = dataDir.listFiles();
11         //构造分析器
12         Analyzer luceneAnalyzer = new StandardAnalyzer(Version.LUCENE_42);
13         //使用分析器构造索引生成器
14         IndexWriter indexWriter = new IndexWriter(indexDir, new IndexWriterConfig(Version.LUCENE_42, luceneAnalyzer));
15         indexWriter.deleteAll();
16         //开始生成索引
17         for (int i = 0; i < dataFiles.length; i++) {
18             if (dataFiles[i].isFile() && dataFiles[i].getName().endsWith(".txt")) {
19                 Document document = new Document();
20                 //以文件名作为path域的内容,Field.Store.YES表示会将其存储到索引中,从而可以直接通过索引查询到内容
21                 document.add(new StringField("path", dataFiles[i].getCanonicalPath(), Field.Store.YES));
22                 //以文件内容作为contents域的内容,Field.Store.NO表示不将其存储到索引中,这样的话,可以根据其关键字查询到索引,但是查询不到具体内容。
23                 document.add(new TextField("contents", FileUtils.readFileToString(dataFiles[i], "GBK"), Field.Store.NO));
24                 indexWriter.addDocument(document);
25             }
26         }
27         //commit和close合二为一。
28         indexWriter.close();
29     }
30 /**
31      * 根据索引进行检索
32      *
33      * @param indexDir        索引文件存放位置
34      * @param keyword         索引关键字
35      * @param numberOfRecords 需要查询出几条记录
36      */
37     public static List<String> search(String indexDir, String keyword, int numberOfRecords) throws IOException {
38         //打开索引文件
39         Directory indexDirectory = FSDirectory.open(new File(indexDir));
40         DirectoryReader ireader = DirectoryReader.open(indexDirectory);
41         //构造索引查询器
42         IndexSearcher isearcher = new IndexSearcher(ireader);
43         //构造查询语句
44         Query query = new TermQuery(new Term("contents", keyword));
45         //进行查询
46         ScoreDoc[] hits = isearcher.search(query, null, numberOfRecords).scoreDocs;
47         List<String> result = new ArrayList<String>();
48         //遍历查询结果
49         for (ScoreDoc scoreDoc : hits)
50             result.add(isearcher.doc(scoreDoc.doc).get("path"));
51         return result;
52     }

完成上面的代码后,就可以对对某个文件夹下的所有文件构建索引并进行查询了,经测试,对英文文件的索引是相当给力的。

这里啰嗦一下自己对Lucene原理的理解,Lucene建立索引的过程为:

1 对需要建立索引的内容进行分词,得到关键字。

2 对关键字进行加工,加工过程包括:过滤,过滤掉语气助词,如and、or、to等;大小写转化,因为人们可能希望查询"Computer"的时候,可以查询到"computer"、"COMPUTER"等相关词;词态转化,如希望在查询"want"的时候,可以查询到"wants","wanted"等等。

3 根据关键字建立索引,即记录某个关键字在哪些文档中出现过。

大致过程就是这样,更细节的优化还没有看,想着等将来需要深层次使用的时候再去看吧。

上面这些步骤完成后,就可以方面的进行查询了。

如果大家比较细心的话,就会发现我上面专门强调“对英文文件的索引是相当给力的”,也就说明对中文文件的索引相当不给力,这是因为英文分词相对比较容易,根据空白字符和标点符号基本上就可以分词了,但是中文分词比较有难度(可以百度“清明时节雨纷纷 断词”,然后自己体会),因此如果需要对中文文件建立索引时,需要使用其他的分词包,做的比较出色的有Lucene自带的SmartCN和IKAnalyzer。这两个分词包的使用也比较简单:

需要使用SmartCN时,引入SmartCN的包(在analysis下面的smartcn下),然后将上面代码的第12行改为:

1 Analyzer luceneAnalyzer = new SmartChineseAnalyzer(Version.LUCENE_42);

即可。

需要使用IKAnalyzer时,引入IKAnalyzer的包(网上自行搜索),然后将上面代码的第12行改为:

1 Analyzer luceneAnalyzer = new IKAnalyzer();

即可。

再次感谢面向对象这个伟大的发明!

以上就是我对Lucene当前的理解了,如果项目中真正用到Lucene时,再深入学习吧。

本文涉及代码已在Oschina的Git上共享了,链接为:http://git.oschina.net/xdxn/Test

参考文献:

开源中文分词框架分词效果对比smartcn与IKanalyzer

Lucene 工作原理

Lucene初试

标签:

原文地址:http://www.cnblogs.com/qq690388648/p/first_see_of_lucene.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!