lucene:有关lucene的笔记一

  这个东西在2006年初,我就开始在项目中使用.我对它也有了些了解. 但主要开发还是小兵们在做. 所以仅仅了解了些皮毛. 下面我将以知识点形式, 列出来. 以笔记形式连载. 也方便大家起学习. 每个点, 我都会写个知识点.

  1, 2005年时候, 听说了lucene. 是个开源搜索引擎开发包. 而不是个搜索引擎,请切记.

  2, 如果开始学习它, 就需要至少知道,它所包含包. 目前lucene已经到了2.2版本. 当然你需要时刻关注他最新版本. 目前包: lucene-core-2.2.0.jar . 下载可以到apache网站WebSite上下载. 这个就够了.不用下别.

  3, 下面问题会接踵而至, 我挨着写,你挨着看即可.

  分词. 第个要涉及问题, 分词就是将句话中关键词汇分离出来, 然后才可以建立索引. 例如 中华人民共和国 --> 中华, 中华人民 华人,人民, 共和国,等. lucene缺省带了个标准分词类: StandardAnalyzer 这个按字来分. 从网上发现了很多员写开源分词类. 当然都是继承了luceneorg.apache.lucene.analysis.Analyze类. 以实现更好更快分词效果. 可以搜索获取更多, 般分词类,都提供了可检测分词效果思路方法. 输入个长句, 然后执行,看看分词效果和执行时间.

  4, ThesaurusAnalyzer是个哥们开发,网上有源码可以下载. 从这个源码里面对分词可以有更深入了解: 包括那些是词汇,那些不是词汇. 都在文本文件里面以行分割开来. 由此可以知道: 分词是需要词库. 词库可以不断扩充 .但每次构造分词对象时,是建立在当前词库基础上. 如果词库动态增加了新词汇, 需要重新构建分词对象. 当然, 也可以读取数据库.

  5, 上面分词, 也仅仅是分词! 网上有人提出问题是: 索引中,加入了"东北大学". "北大" . 要搜索 北大 , 显然我们没有找到东北大学意思. 但最后还是找到了. 东北大学 4个字里面有北大两个字. 分词时这个词被确认是个词, 就加入了索引. 这种情况, 涉及到汉语语义问题 .暂时不好解决. 所以不提.

  选择较好分析器

  这个优化主要是对磁盘空间优化可以将索引文件减小将近相同测试数据下由600M减少到380M但是对时间并没有什么帮助甚至会需要更长时间较好分析器需要匹配词库会消耗更多cpu测试数据用StandardAnalyzer耗时133分钟;用MMAnalyzer耗时150分钟

  6, 分词缺失: 就似乎同义词. 为了减少用户搜索次数, 增加搜索效果. 如果用户搜 "北京 饭店" 能不能把" 首都 饭店"也列出来呢. 这个分词器无能为力. 我也考虑到这个问题, 在北京托尔 4公司TRS搜索产品文档中人家也考虑到了这个问题. 就似乎如果搜索 锐器, 系统会自动把匕首,尖刀等词汇并加入搜索结果. 所以这个问题 ,就只能是在分词的前,我们再加层:同义词返回模块. 这个思路很不错, 也比较简单. 很容易实现. 关键是词库建立. 这个就说到这里.

  7, 说到这里,你可能想要做个例子来实战下. 做个例子很容易. 网上很多. 我只做简单叙述: lucene是用目录或者内存来存储数据. 可以设定. 但是实战证明RAMDirectory和FSDirectory速度差不多当数据量很小时两者都非常快当数据量较大时(索引文件400M)RAMDirectory甚至比FSDirectory还要慢这确实让人出乎意料

  而且lucene搜索非常耗内存即使将400M索引文件载入内存在运行段时间后都会out of memory所以个人认为载入内存作用并不大

  我们用目录:

  如下:

//构建个 IndexWriter 用来写如索引
File indexDir = File(
"E:javasourceLuceneTestindex");
IndexWriter indexWriter = IndexWriter(indexDir,
ThesaurusAnalyzer, false);
Document doc = Document( Article("name"+i, "北京老张"));
indexWriter.addDocument(doc);
indexWrite.close;


  由上可以看出, lucene将在这个目录下进行操作. 上面代码中你不要抄袭当例子, 还有个Article类和Document思路方法.里面也有些东西. 现在仅仅先理解上面意思即可. 操作前,你可能不知道他会在目录里干什么.

  8, 目录下东西 . 如果测试成功, 目录下有 3个文件.

  segments.gen segments_a08, 还有个类似 _uw.cfs名字东西. 当然,不定都样, 但肯定是这 3个. 如果出现了很多文件.不要着急, 看下面 9 .

  9, 如果lucene索引目录下出现了很多文件, 肯定是有问题. 几个方面.首先lucene在执行写操作时, 会先在目录下写如个write.lock文件锁定这个目录,以避免别索引再操作这个路径. 否则那样肯定会乱. 锁定的后, 开始写索引, 写索引时lucene建了几个或者几十个临时片段文件, 都似乎又短又乱.cfs文件. 当索引建立完毕后,没有执行 indexWriter.optimize;思路方法, 他就不会合并那些乱 7 8糟文件. 所以,索引建完后, 定要执行 上面优化思路方法, 保持目录下保留3个文件即可. 也就是很多临时文件会合并到个文件中去. 切不可大意删除. 但当数据很多时, 另行考虑策略.

  10, lucene在写入索引时, 用在索引目录下建write.lock文件来标识锁定. 而只有在执行close思路方法后, 才会删除这个锁文件. 只要这个文件存在, 其他写索引都会报错:

caught a org.apache.lucene.store.LockObtainFailedException
with message: Lock obtain timed out: SimpleFSLock@E:javasourceLuceneTestindexwrite.lock


  所以,需要注意, 定要注意关闭indexWrite. 包括异常下,用finally关闭.否则会导致下次写索引失败.

  11, 批量增加索引, 如果要成批用循环加入索引,该如何办呢. 首先请注意: IndexWriter indexWriter = IndexWriter(indexDir,



   ThesaurusAnalyzer, false); 最后个参数为false表示持续想索引增加数据. 如果为true, 则每次会删除全部, 重新开始.

  12, 在批量增加索引时, 可以直执行

  indexWriter.addDocument(doc); 但不能直执行优化:indexWriter.optimize; 优化思路方法比较耗时, 特别是当索引很大时, 更要注意. 优化, 也仅仅似乎优化会消耗很多时间和cpu. 所以这个时候.多几个文件也没关系. 网上有个人问了这样问题, 我摘录如下, 用等号分割开我内容:

  引自:

  http://www.javaeye.com/topic/107818?page=3



Tags:  lucene教程 lucene.net luceneinaction lucene

延伸阅读

最新评论

发表评论