上周,拿出了去年写的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这个包,然后调用它里面的方法就可以了。主要代码如下:
上面这段代码就已经对关键词进行了高亮的处理,高亮处理后,关键词的在网页的显示效果为
当初令我困扰的地方并不是如何实现高亮,毕竟实现高亮的代码google一下有很多,真正令我困扰的是如果将处理后的结果显示到网页上?因为我要返回一个List给前端页面, 这个List中存储的是Lucene的Document,但是在做高亮处理时,是将Docuemnt的内容取出放到了String类型的变量里,最初的时候,由于脑子一时没转过来所以一直不知道该如何在页面上显示,经过一个周末的休息,周一上班时脑子突然活络——将处理好的内容再重新封装到Lucene的Document中,不就可以像没处理前一样,添加到List里然后返回给前端页面了吗,我怎么早没想到呢。封装代码如下:
搜索结果如下图:
嗯,总体来说效果不错,还算比较满意,有时间改成可以动态维护的,哈哈。好有成就感,嘎嘎
下载了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这个包,然后调用它里面的方法就可以了。主要代码如下:
TokenStream tokenStream =
null;
/** 添加关键词高亮显示 start */
Document doc = hits.doc(i);
SimpleHTMLFormatter simpleHTMLFormatter = new SimpleHTMLFormatter( "<span style='color:#FF0000; background-color:#FFFF00'>", "</span>");
Highlighter highlighter = new Highlighter(simpleHTMLFormatter, new QueryScorer(query));
/** 对标题进行高亮处理 */
String title = "";
String titleTmp = doc.get( "title");
highlighter.setTextFragmenter( new SimpleFragmenter(titleTmp.length()));
if (titleTmp != null)
{
tokenStream = TokenSources.getAnyTokenStream(reader, hits.id(i), "title", analyzer);
title = highlighter.getBestFragment(tokenStream, titleTmp);
}
/** 对内容进行高亮处理 */
String content = "";
String contentTmp = doc.get( "content");
highlighter.setTextFragmenter( new SimpleFragmenter(contentTmp.length()));
if (contentTmp != null)
{
tokenStream = TokenSources.getAnyTokenStream(reader, hits.id(i), "content", analyzer);
content = highlighter.getBestFragment(tokenStream, contentTmp);
}
/** 添加关键词高亮显示 end */
/** 添加关键词高亮显示 start */
Document doc = hits.doc(i);
SimpleHTMLFormatter simpleHTMLFormatter = new SimpleHTMLFormatter( "<span style='color:#FF0000; background-color:#FFFF00'>", "</span>");
Highlighter highlighter = new Highlighter(simpleHTMLFormatter, new QueryScorer(query));
/** 对标题进行高亮处理 */
String title = "";
String titleTmp = doc.get( "title");
highlighter.setTextFragmenter( new SimpleFragmenter(titleTmp.length()));
if (titleTmp != null)
{
tokenStream = TokenSources.getAnyTokenStream(reader, hits.id(i), "title", analyzer);
title = highlighter.getBestFragment(tokenStream, titleTmp);
}
/** 对内容进行高亮处理 */
String content = "";
String contentTmp = doc.get( "content");
highlighter.setTextFragmenter( new SimpleFragmenter(contentTmp.length()));
if (contentTmp != null)
{
tokenStream = TokenSources.getAnyTokenStream(reader, hits.id(i), "content", analyzer);
content = highlighter.getBestFragment(tokenStream, contentTmp);
}
/** 添加关键词高亮显示 end */
当初令我困扰的地方并不是如何实现高亮,毕竟实现高亮的代码google一下有很多,真正令我困扰的是如果将处理后的结果显示到网页上?因为我要返回一个List给前端页面, 这个List中存储的是Lucene的Document,但是在做高亮处理时,是将Docuemnt的内容取出放到了String类型的变量里,最初的时候,由于脑子一时没转过来所以一直不知道该如何在页面上显示,经过一个周末的休息,周一上班时脑子突然活络——将处理好的内容再重新封装到Lucene的Document中,不就可以像没处理前一样,添加到List里然后返回给前端页面了吗,我怎么早没想到呢。封装代码如下:
/** 重新封装Lucene的Docuemnt */
Document docTmp = new Document();
docTmp.add( new Field( "docid", doc.get( "docid"),Field.Store.YES, Field.Index.NO));
/** 添加title */
docTmp.add( new Field( "title", title,Field.Store.YES, Field.Index.TOKENIZED,Field.TermVector.WITH_POSITIONS_OFFSETS));
/** 添加content */
docTmp.add( new Field( "content", content, Field.Store.YES,Field.Index.TOKENIZED,Field.TermVector.WITH_POSITIONS_OFFSETS));
docTmp.add( new Field( "url", doc.get( "url"),Field.Store.YES, Field.Index.NO));
/** 将封装好的Document添加到List中 */
listTmp.add(docTmp);
Document docTmp = new Document();
docTmp.add( new Field( "docid", doc.get( "docid"),Field.Store.YES, Field.Index.NO));
/** 添加title */
docTmp.add( new Field( "title", title,Field.Store.YES, Field.Index.TOKENIZED,Field.TermVector.WITH_POSITIONS_OFFSETS));
/** 添加content */
docTmp.add( new Field( "content", content, Field.Store.YES,Field.Index.TOKENIZED,Field.TermVector.WITH_POSITIONS_OFFSETS));
docTmp.add( new Field( "url", doc.get( "url"),Field.Store.YES, Field.Index.NO));
/** 将封装好的Document添加到List中 */
listTmp.add(docTmp);
搜索结果如下图:
嗯,总体来说效果不错,还算比较满意,有时间改成可以动态维护的,哈哈。好有成就感,嘎嘎
本文转自 sw840227 51CTO博客,原文链接:http://blog.51cto.com/jerrysun/191376,如需转载请自行联系原作者