这个东西在2006年初,我就开始在项目中使用.我对它也有了
![](/icons/53676yi.gif)
些了解. 但
![](/icons/53676yinwei.gif)
主要开发还是小兵们在做. 所以仅仅了解了
![](/icons/53676yi.gif)
些皮毛. 下面我将以知识点
![](/icons/53676de.gif)
形式, 列出来. 以笔记
![](/icons/53676de.gif)
形式连载. 也方便大家
![](/icons/53676yi.gif)
起学习. 每
![](/icons/53676yi.gif)
个点, 我都会写
![](/icons/53676yi.gif)
个知识点.
1, 2005年
![](/icons/53676de.gif)
时候, 听说了lucene. 是
![](/icons/53676yi.gif)
个开源
![](/icons/53676de.gif)
搜索引擎开发包. 而不是
![](/icons/53676yi.gif)
个搜索引擎,请切记.
2, 如果开始学习它, 就需要至少知道,它所包含
![](/icons/53676de.gif)
包. 目前lucene已经到了2.2版本. 当然你需要时刻关注他
![](/icons/53676de.gif)
最新版本. 目前包: lucene-core-2.2.0.jar . 下载可以到apache
![](/icons/53676de.gif)
网站WebSite上下载. 这
![](/icons/53676yi.gif)
个就够了.不用下别
![](/icons/53676de.gif)
.
3, 下面问题会接踵而至, 我挨着写,你挨着看即可.
分词. 第
![](/icons/53676yi.gif)
个要涉及
![](/icons/53676de.gif)
问题, 分词就是将
![](/icons/53676yi.gif)
句话中
![](/icons/53676de.gif)
关键词汇分离出来, 然后才可以建立索引. 例如 中华人民共和国 --> 中华, 中华人民 华人,人民, 共和国,等. lucene缺省带了
![](/icons/53676yi.gif)
个标准分词
![](/icons/53676de.gif)
类: StandardAnalyzer 这个按字来分
![](/icons/53676de.gif)
. 从网上发现了很多
![](/icons/53676chengxu.gif)
员写
![](/icons/53676de.gif)
开源
![](/icons/53676de.gif)
分词
![](/icons/53676de.gif)
类. 当然都是继承了lucene
![](/icons/53676de.gif)
org.apache.lucene.analysis.Analyze类. 以实现更好更快
![](/icons/53676de.gif)
分词效果. 可以搜索获取更多,
![](/icons/53676yi.gif)
般分词
![](/icons/53676de.gif)
类,都提供了可检测分词效果
![](/icons/53676de.gif)
思路方法. 输入
![](/icons/53676yi.gif)
个长句, 然后执行,看看分词效果和执行时间.
4, ThesaurusAnalyzer是
![](/icons/53676yi.gif)
个哥们开发
![](/icons/53676de.gif)
,网上有源码可以下载. 从这个源码里面对分词可以有更深入
![](/icons/53676de.gif)
了解: 包括那些是词汇,那些不是词汇. 都在文本文件里面以行分割开来. 由此可以知道: 分词是需要词库
![](/icons/53676de.gif)
.
![](/icons/53676yinwei.gif)
词库可以不断
![](/icons/53676de.gif)
扩充 .但每次构造分词对象时,是建立在当前词库基础上
![](/icons/53676de.gif)
. 如果词库动态增加了新
![](/icons/53676de.gif)
词汇, 需要重新构建分词对象. 当然, 也可以读取数据库.
5, 上面
![](/icons/53676de.gif)
分词, 也仅仅是分词! 网上有人提出
![](/icons/53676de.gif)
问题是: 索引中,加入了"东北大学". "北大" . 要搜索 北大 , 显然我们没有找到东北大学
![](/icons/53676de.gif)
意思. 但最后还是找到了.
![](/icons/53676yinwei.gif)
东北大学 4个字里面有北大两个字. 分词时这个词被确认是个词, 就加入了索引. 这种情况, 涉及到汉语语义
![](/icons/53676de.gif)
问题 .暂时不好解决. 所以不提.
选择较好
![](/icons/53676de.gif)
分析器
这个优化主要是对磁盘空间
![](/icons/53676de.gif)
优化
![](/icons/53676dou.gif)
可以将索引文件减小将近
![](/icons/53676yi.gif)
半
![](/icons/53676dou.gif)
相同测试数据下由600M减少到380M
![](/icons/53676dou2.gif)
但是对时间并没有什么帮助
![](/icons/53676dou.gif)
甚至会需要更长时间
![](/icons/53676dou.gif)
![](/icons/53676yinwei.gif)
较好
![](/icons/53676de.gif)
分析器需要匹配词库
![](/icons/53676dou.gif)
会消耗更多cpu
![](/icons/53676dou.gif)
测试数据用StandardAnalyzer耗时133分钟;用MMAnalyzer耗时150分钟
![](/icons/53676dou2.gif)
6, 分词
![](/icons/53676de.gif)
缺失: 就似乎同义词. 为了减少用户搜索
![](/icons/53676de.gif)
次数, 增加搜索效果. 如果用户搜 "北京 饭店" 能不能把" 首都 饭店"也列出来呢. 这个分词器无能为力. 我也考虑到这个问题, 在北京托尔 4公司
![](/icons/53676de.gif)
TRS
![](/icons/53676de.gif)
搜索产品文档中人家也考虑到了这个问题. 就似乎如果搜索 锐器, 系统会自动把匕首,尖刀等词汇
![](/icons/53676yi.gif)
并加入搜索结果. 所以这个问题 ,就只能是在分词的前,我们再加
![](/icons/53676yi.gif)
层:同义词返回模块. 这个思路很不错, 也比较简单. 很容易实现. 关键是词库
![](/icons/53676de.gif)
建立. 这个就说到这里.
7, 说到这里,你可能想要做个例子来实战
![](/icons/53676yi.gif)
下. 做个例子很容易. 网上很多. 我只做简单
![](/icons/53676de.gif)
叙述: lucene是用目录或者内存来存储数据
![](/icons/53676de.gif)
. 可以设定. 但是实战证明RAMDirectory和FSDirectory速度差不多
![](/icons/53676dou.gif)
当数据量很小时两者都非常快
![](/icons/53676dou.gif)
当数据量较大时(索引文件400M)RAMDirectory甚至比FSDirectory还要慢
![](/icons/53676yi.gif)
点
![](/icons/53676dou.gif)
这确实让人出乎意料
![](/icons/53676dou2.gif)
而且lucene
![](/icons/53676de.gif)
搜索非常耗内存
![](/icons/53676dou.gif)
即使将400M
![](/icons/53676de.gif)
索引文件载入内存
![](/icons/53676dou.gif)
在运行
![](/icons/53676yi.gif)
段时间后都会out of memory
![](/icons/53676dou.gif)
所以个人认为载入内存
![](/icons/53676de.gif)
作用并不大
![](/icons/53676dou2.gif)
我们用目录:
如下:
//构建
个 IndexWriter 用来写如索引
File indexDir =
File(
"E:javasourceLuceneTestindex");
IndexWriter indexWriter =
IndexWriter(indexDir,
ThesaurusAnalyzer
, false);
Document doc = Document(
Article("name"+i, "北京老张"));
indexWriter.addDocument(doc);
indexWrite.close
;
由上可以看出, lucene将在这个目录下进行操作. 上面代码中
![](/icons/53676de.gif)
你不要抄袭当例子,
![](/icons/53676yinwei.gif)
还有
![](/icons/53676yi.gif)
个Article类和Document思路方法.里面也有
![](/icons/53676yi.gif)
些东西. 现在仅仅先理解上面
![](/icons/53676de.gif)
意思即可. 操作前,你可能不知道他会在目录里干什么.
8, 目录下
![](/icons/53676de.gif)
东西 . 如果测试成功, 目录下有 3个文件.
segments.gen segments_a08, 还有
![](/icons/53676yi.gif)
个类似 _uw.cfs名字
![](/icons/53676de.gif)
东西. 当然,不
![](/icons/53676yi.gif)
定都
![](/icons/53676yi.gif)
样, 但肯定是这 3个. 如果出现了很多文件.不要着急, 看下面
![](/icons/53676de.gif)
9 .
9, 如果lucene
![](/icons/53676de.gif)
索引目录下出现了很多文件, 肯定是有问题
![](/icons/53676de.gif)
. 几个方面.首先lucene在执行写操作时, 会先在目录下写如
![](/icons/53676yi.gif)
个write.lock
![](/icons/53676de.gif)
文件锁定这个目录,以避免别
![](/icons/53676de.gif)
索引再操作这个路径. 否则那样肯定会乱. 锁定的后, 开始写索引, 写索引时lucene建了几个或者几十个临时片段文件, 都似乎又短又乱
![](/icons/53676de.gif)
![](/icons/53676zifu.gif)
.cfs
![](/icons/53676de.gif)
文件. 当索引建立完毕后,没有执行 indexWriter.optimize
![](/icons/53676kh.gif)
;思路方法, 他就不会合并那些乱 7 8糟
![](/icons/53676de.gif)
文件. 所以,索引建完后,
![](/icons/53676yi.gif)
定要执行 上面
![](/icons/53676de.gif)
优化思路方法, 保持目录下保留3个文件即可. 也就是很多临时文件会合并到
![](/icons/53676yi.gif)
个文件中去. 切不可大意删除. 但当数据很多时, 另行考虑策略.
10, lucene在写入索引时, 用在索引目录下建write.lock文件来标识锁定. 而只有在执行close
![](/icons/53676kh.gif)
思路方法后, 才会删除这个锁文件. 只要这个文件存在, 其他
![](/icons/53676de.gif)
写索引
![](/icons/53676de.gif)
![](/icons/53676chengxu.gif)
都会报错:
caught a
org.apache.lucene.store.LockObtainFailedException
with message: Lock obtain timed out: SimpleFSLock@E:javasourceLuceneTestindexwrite.lock
所以,需要注意,
![](/icons/53676yi.gif)
定要注意关闭indexWrite. 包括异常下,用finally关闭.否则会导致下
![](/icons/53676yi.gif)
次写索引失败.
11, 批量增加索引, 如果要成批
![](/icons/53676de.gif)
用循环加入索引,该如何办呢. 首先请注意: IndexWriter indexWriter =
![](/icons/53676new.gif)
IndexWriter(indexDir,
![](/icons/53676new.gif)
ThesaurusAnalyzer
![](/icons/53676kh.gif)
, false); 最后
![](/icons/53676yi.gif)
个参数为false表示持续想索引增加数据. 如果为true, 则每次会删除全部, 重新开始.
12, 在批量增加索引时,
![](/icons/53676chengxu.gif)
可以
![](/icons/53676yi.gif)
直执行
indexWriter.addDocument(doc); 但不能
![](/icons/53676yi.gif)
直执行优化:indexWriter.optimize
![](/icons/53676kh.gif)
;
![](/icons/53676yinwei.gif)
优化思路方法比较耗时, 特别是当索引很大时, 更要注意.
![](/icons/53676yinwei.gif)
优化, 也仅仅似乎优化会消耗很多时间和cpu. 所以这个时候.多几个文件也没关系. 网上有个人问了这样
![](/icons/53676de.gif)
问题, 我摘录如下, 用等号分割开我
![](/icons/53676de.gif)
内容:
引自:
http://www.javaeye.com/topic/107818?page=3
延伸阅读
最新评论