Lucene初试

从知道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 工作原理

时间: 2024-11-03 23:29:27

Lucene初试的相关文章

Lucene初试——关于大文本建立索引和中文乱码以及QueryParser检索的一些体会

这几天因为一个小项目用到Lucene,于是去学习了一下,现在还有很多地方没有了解,先就我遇到的问题做下总结. 一.大文本建索引问题 我这里说的大文本,实际上也就200M左右的txt,或许不应该成为大文本,但是我在建索引时遇到200M左右的的确导致了内存溢出,报错误java.lang.OutOfMemoryError: Java heap space ,到网上查了很久,试了一些方法,比如修改JVM的运行参数等,都不行.我测试的机器为i5四核,4G内存,实测时可用内存1G多,按说对于200M的文本不

Ubuntu Nginx uwsgi django 初试

/************************************************************************************** * Ubuntu Nginx uwsgi django 初试 * 说明: * 最近打算通过Python搭建一个数据收集的网站,先做一个搭建测试. * * 2016-8-5 深圳 南山平山村 曾剑锋 ***************************************************************

lucene中Field.Index,Field.Store的一些设置

lucene在doc.add(new Field("content",curArt.getContent(),Field.Store.NO,Field.Index.TOKENIZED)); Field有两个属性可选:存储和索引. 通过存储属性你可以控制是否对这个Field进行存储: 通过索引属性你可以控制是否对该Field进行索引. 事实上对这两个属性的正确组合很重要. Field.Index Field.Store 说明 TOKENIZED(分词) YES 被分词索引且存储 TOKE

Lucene 基础理论

1. 全文检索系统与Lucene简介 1.1 什么是全文检索与全文检索系统 全文检索是指计算机索引程序通过扫描文章中的每一个词,对每一个词建立一个索引,指明该词在文章中出现的次数和位置,当用户查询时,检索程序就根据事先建立的索引进行查找,并将查找的结果反馈给用户的检索方式.这个过程类似于通过字典中的检索字表查字的过程. 全文检索的方法主要分为按字检索和按词检索两种.按字检索是指对于文章中的每一个字都建立索引,检索时将词分解为字的组合.对于各种不同的语言而言,字有不同的含义,比如英文中字与词实际上

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

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

一步一步跟我学习lucene(9)---lucene搜索之拼写检查和相似度查询提示(spellcheck)

suggest应用场景 用户的输入行为是不确定的,而我们在写程序的时候总是想让用户按照指定的内容或指定格式的内容进行搜索,这里就要进行人工干预用户输入的搜索条件了:我们在用百度谷歌等搜索引擎的时候经常会看到按键放下的时候直接会提示用户是否想搜索某些相关的内容,恰好lucene在开发的时候想到了这一点,lucene提供的suggest包正是用来解决上述问题的. suggest包联想词相关介绍 suggest包提供了lucene的自动补全或者拼写检查的支持: 拼写检查相关的类在org.apache.

Lucene的一个简单的标准测试(Lucene包基于3.5版本的)

Lucene编程一般分为:索引.分词.搜索 索引源代码: package lucene的一个标准测试; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStreamReader; import java.util.Date; import org.apache.lucene.anal

利用Lucene把文本的字体格式进行修改,然后输出到一个新的文件中

这里书中写的是charactorProcess(File file, String destFile) 这里被我改成,(String file,  String destFIle) 一个代表现有的文件和要新建的文件 代码: package com; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileReader; import java.io.

Lucene基本概念

Lucene基本概念: 1.  Index:索引库,文档的集合组成索引.和一般的数据库不一样,Lucene不支持定义主键,在Lucene中不存在一个叫做Index的类,通过IndexWriter来写索引,通过IndexReader来读索引.索引库在物理形式上一般是位于一个路径下的一系列文件. 2.  分析器:一段有意义的文字需要通过Analyzer分析器分割成一个个词语后才能按关键字搜索,StandardAnalyzer是Lucene中最常用的分析器.为了达到更好的搜索效果,不同的语言可以使用不