上周,拿出了去年写的Java Lucene程序,虽然一直想将自己写的Lucene搜索程序模块化,但是无奈工作太忙,忙的以至于我忘记了我还写过一个Lucene的搜索程序,最初写这个程序是在2008年9月,到上周进行更改已经过了将近1年的时间,对于中文的分词包也出现了多个版本,发现目前比较流行的中文分词包是“庖丁(Paoding)”,既然如此,那我也不能继续使用JE分词包了,怎么办——换。
  下载了paoding-analysis-2.0.1(UTF-8).zip,解压缩之后,将paoding-analysis.jar放到了WEB-INF下的lib目录下,根据网上同行们的经验,Paoding需要修改一个名为“paoding-analysis.properties”的文件,主要目的是用来更改Paoding的Dic目录的存放位置,根据以往的习惯,这个Dic文件夹,被我放到了网站的根目录下,为了方便,我在paoding-analysis.properties文件中,将paoding.dic.home的值写成了绝对路径。一切准备就绪,可以执行搜索了,结果报错,错误信息如下:“error at net.paoding.analysis.exception.PaodingAnalysisException: Wrong paoding analysis config:null”。呀,这是啥原因,得,赶紧google一下吧,查了N多,说什么的都有,完,这回可是傻了眼了,没遇见过啊,没招了,一个一个试吧,所有方法都试过了,每一个管用的,这是为啥呢?再仔细的看,嘿嘿,终于被我发现错在什么地方了——路径错了,paoding-analysis.properties这个文件应该放在WEB-INF\classes这个目录下,结果我给放到了class所在的文件夹里,能找到才怪呢。错误解决,继续下面的工作。
  要说这高亮,还是比较好搞的,就是要引用luncene的highlight这个包,然后调用它里面的方法就可以了。主要代码如下:
InBlock.gifTokenStream tokenStream = null;
InBlock.gif                            
InBlock.gif /** 添加关键词高亮显示 start */
InBlock.gifDocument doc = hits.doc(i);
InBlock.gif                
InBlock.gifSimpleHTMLFormatter simpleHTMLFormatter = new SimpleHTMLFormatter( "<span style='color:#FF0000; background-color:#FFFF00'>", "</span>");    
InBlock.gifHighlighter highlighter = new Highlighter(simpleHTMLFormatter, new QueryScorer(query));
InBlock.gif                            
InBlock.gif /** 对标题进行高亮处理 */
InBlock.gifString title = "";
InBlock.gifString titleTmp = doc.get( "title");
InBlock.gifhighlighter.setTextFragmenter( new SimpleFragmenter(titleTmp.length()));
InBlock.gif                            
InBlock.gif if (titleTmp != null)
InBlock.gif{    
InBlock.gif  tokenStream = TokenSources.getAnyTokenStream(reader, hits.id(i), "title", analyzer);
InBlock.gif  title = highlighter.getBestFragment(tokenStream, titleTmp);
InBlock.gif}
InBlock.gif                            
InBlock.gif /** 对内容进行高亮处理 */
InBlock.gifString content = "";
InBlock.gifString contentTmp = doc.get( "content");
InBlock.gifhighlighter.setTextFragmenter( new SimpleFragmenter(contentTmp.length()));
InBlock.gif                            
InBlock.gif if (contentTmp != null)
InBlock.gif{    
InBlock.gif  tokenStream = TokenSources.getAnyTokenStream(reader, hits.id(i), "content", analyzer);
InBlock.gif  content = highlighter.getBestFragment(tokenStream, contentTmp);
InBlock.gif}
InBlock.gif /** 添加关键词高亮显示 end */
  上面这段代码就已经对关键词进行了高亮的处理,高亮处理后,关键词的在网页的显示效果为
  当初令我困扰的地方并不是如何实现高亮,毕竟实现高亮的代码google一下有很多,真正令我困扰的是如果将处理后的结果显示到网页上?因为我要返回一个List给前端页面,这个List中存储的是Lucene的Document,但是在做高亮处理时,是将Docuemnt的内容取出放到了String类型的变量里,最初的时候,由于脑子一时没转过来所以一直不知道该如何在页面上显示,经过一个周末的休息,周一上班时脑子突然活络——将处理好的内容再重新封装到Lucene的Document中,不就可以像没处理前一样,添加到List里然后返回给前端页面了吗,我怎么早没想到呢。封装代码如下:
InBlock.gif /** 重新封装Lucene的Docuemnt */
InBlock.gifDocument docTmp = new Document();
InBlock.gifdocTmp.add( new Field( "docid", doc.get( "docid"),Field.Store.YES, Field.Index.NO));
InBlock.gif /** 添加title */
InBlock.gifdocTmp.add( new Field( "title", title,Field.Store.YES, Field.Index.TOKENIZED,Field.TermVector.WITH_POSITIONS_OFFSETS));
InBlock.gif /** 添加content */
InBlock.gifdocTmp.add( new Field( "content", content, Field.Store.YES,Field.Index.TOKENIZED,Field.TermVector.WITH_POSITIONS_OFFSETS));
InBlock.gifdocTmp.add( new Field( "url", doc.get( "url"),Field.Store.YES, Field.Index.NO));
InBlock.gif                            
InBlock.gif /** 将封装好的Document添加到List中 */
InBlock.giflistTmp.add(docTmp);
  
  搜索结果如下图:

  嗯,总体来说效果不错,还算比较满意,有时间改成可以动态维护的,哈哈。好有成就感,嘎嘎