lucence 高亮

一、Lucene 中文引擎,庖丁解牛的辞典参数配置方法(转)

随机文档指示可以在环境变量里配置。原文如下
庖丁中文分词需要一套词典,这些词典需要统一存储在某个目录下,这个目录称为词典安装目录。词典安装目录可以是文件系统的任何目录,它不依赖于应用程序的运行目录。将词典拷贝到词典安装目录的过程称为安装词典。增加、删除、修改词典目录下的词典的过程称为自定制词典。

在linux下,我们可以考虑将词典安装在一个专门存储数据的分区下某目录,以笔者为例,笔者将/data作为系统的一个独立分区,笔者便是将词典保存在/data/paoding/dic下。
在windows下,我们可以考虑将词典安装在非系统盘的另外分区下的某个目录,以笔者为例,笔者可能将词典保存在E:/data/paoding/dic下。
使用者安装辞典后,应该设置系统环境变量PAODING_DIC_HOME指向词典安装目录。
在linux下,通过修改/etc/profile,在文件末尾加上以下2行,然后保存该文件并退出即可。
PAODING_DIC_HOME=/data/paoding/dic
export PAODING_DIC_HOME
在windows下,通过“我的电脑”属性之“高级”选项卡,然后在进入“环境变量”编辑区,新建环境变量,设置“变量名”为PAODING_DIC_HOME;“变量值”为E:/data/paoding/dic


不过我在错误信息里面发现了另外一个配置方式,那就是修改paoding-dic-home.properties 里面的 paoding.dic.home 配置
这个文件在
paoding-analysis-2.0.4-beta\classes
有一个,我们可以修改这个,原始内容如下

#values are "system-env" or "this";
#if value is "this" , using the paoding.dic.home as dicHome if configed!
#paoding.dic.home.config-fisrt=system-env

#dictionary home (directory)
#"classpath:xxx" means dictionary home is in classpath.
#e.g "classpath:dic" means dictionaries are in "classes/dic" directory or any other classpath directory
#paoding.dic.home=dic

#seconds for dic modification detection
#paoding.dic.detector.interval=60


我们修改成如下内容
#values are "system-env" or "this";
#if value is "this" , using the paoding.dic.home as dicHome if configed!
# 这里修改为 this 代表使用这个配置而不是环境变量的配置
paoding.dic.home.config-fisrt=this

#dictionary home (directory)
#"classpath:xxx" means dictionary home is in classpath.
#e.g "classpath:dic" means dictionaries are in "classes/dic" directory or any other classpath directory
# 这里修改为我们辞典所在的目录
paoding.dic.home=E:/lib/paoding-analysis-2.0.4-beta/dic/

#seconds for dic modification detection
#paoding.dic.detector.interval=60


最后一步,用winrar/winzip等打开 paoding-analysis.jar 然后更新里面的 paoding-dic-home.properties

OK, 这个jar就是我们自己使用的了。

 

二、实例

 

任务1 到此完成,新闻显示工作结束。下面是搜索引擎部分。

 

搜索的工具类放置在com.zly.indexManager包下面

 

说明,本程序使用了庖丁解牛中文分词,用户使用时需要中文字典,我的字典放在了c:\dic下面,使用庖丁还需要配置环境变量PAODING_DIC_HOME , 其值为c:\dic , (就是你的字典文件所在的目录)

 

代码如下:

 

创建索引类IndexCreateUtil

 

Java代码   复制代码  收藏代码
  1. package com.zly.indexManager;   
  2.   
  3. import java.io.File;   
  4. import java.text.DateFormat;   
  5. import java.text.SimpleDateFormat;   
  6. import java.util.List;   
  7.   
  8. import net.paoding.analysis.analyzer.PaodingAnalyzer;   
  9.   
  10. import org.apache.lucene.analysis.Analyzer;   
  11. import org.apache.lucene.document.Document;   
  12. import org.apache.lucene.document.Field;   
  13. import org.apache.lucene.index.IndexWriter;   
  14. import org.hibernate.SessionFactory;   
  15. import org.hibernate.cfg.AnnotationConfiguration;   
  16. import org.hibernate.cfg.Configuration;   
  17. import org.hibernate.Session;   
  18. import org.htmlparser.Parser;   
  19.   
  20. import com.zly.test.entity.NewsItem;   
  21.   
  22. public class IndexCreateUtil {   
  23.        
  24.     @SuppressWarnings("unchecked")   
  25.     public void createIndexForNews() throws Exception {   
  26.         //存放索引的文件夹   
  27.         File indexFile = new File("c:/index/news");   
  28.         //使用了庖丁解牛分词器   
  29.         Analyzer analyzer = new PaodingAnalyzer();   
  30.         //使用索引文件夹,庖丁解牛分词器创建IndexWriter   
  31.         IndexWriter indexWriter = new IndexWriter(indexFile , analyzer , true);   
  32.         //从数据库中读取出所有的新闻记录以便进行索引的创建   
  33.         Configuration cfg = new AnnotationConfiguration().configure();   
  34.         SessionFactory factory = cfg.buildSessionFactory();   
  35.         Session session = factory.openSession();   
  36.         List<NewsItem> list = session.createQuery(" from NewsItem").list();   
  37.         DateFormat format = new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒");   
  38.         //对所有的新闻实体进行索引创建   
  39.         for (NewsItem newsItem : list) {   
  40.             //建立一个lucene文档   
  41.             Document doc = new Document();   
  42.             //得到新闻标题   
  43.             String newsTitle = newsItem.getNewsTitle();   
  44.             //得到新闻内容   
  45.             String newsContent = newsItem.getNewsContent();   
  46.             //得到新闻事件   
  47.             String publishDate = format.format(newsItem.getPublishTime());   
  48.             //得到新闻主键id   
  49.             String id = newsItem.getId() + "";   
  50.             //将新闻标题加入文档,因为要搜索和高亮,所以index是tokennized,TermVector是WITH_POSITIONS_OFFSETS   
  51.             doc.add(new Field("title" , newsTitle , Field.Store.YES , Field.Index.TOKENIZED , Field.TermVector.WITH_POSITIONS_OFFSETS));   
  52.             //利用htmlparser得到新闻内容html的纯文本   
  53.             Parser parser = new Parser();   
  54.             parser.setInputHTML(newsContent);   
  55.             String strings = parser.parse(null).elementAt(0).toPlainTextString().trim();   
  56.             //添加新闻内容至文档,与标题相似   
  57.             doc.add(new Field("content" , strings , Field.Store.COMPRESS , Field.Index.TOKENIZED , Field.TermVector.WITH_POSITIONS_OFFSETS));   
  58.             //添加时间至文档,因为要按照此字段降序排列排序,所以tokenzied,不用高亮所以TermVector是no就行了   
  59.             doc.add(new Field("date" , publishDate , Field.Store.YES , Field.Index.TOKENIZED , Field.TermVector.NO));   
  60.             //添加主键至文档,不分词,不高亮。   
  61.             doc.add(new Field("id" , id , Field.Store.YES , Field.Index.NO , Field.TermVector.NO));   
  62.             indexWriter.addDocument(doc);   
  63.         }   
  64.         //创建索引   
  65.         indexWriter.optimize();   
  66.         indexWriter.close();   
  67.         //关闭session   
  68.         session.close();   
  69.     }   
  70.     public static void main(String[] args) throws Exception {   
  71.         IndexCreateUtil util  = new IndexCreateUtil();   
  72.         util.createIndexForNews();   
  73.     }   
  74. }  

 

对索引进行搜索的代码如下:

 

  

Java代码   复制代码  收藏代码
  1. package com.zly.indexManager;   
  2.   
  3. import java.io.File;   
  4. import java.util.ArrayList;   
  5. import java.util.List;   
  6.   
  7. import net.paoding.analysis.analyzer.PaodingAnalyzer;   
  8.   
  9. import org.apache.lucene.analysis.Analyzer;   
  10. import org.apache.lucene.document.Document;   
  11. import org.apache.lucene.index.IndexReader;   
  12. import org.apache.lucene.queryParser.QueryParser;   
  13. import org.apache.lucene.search.Hits;   
  14. import org.apache.lucene.search.IndexSearcher;   
  15. import org.apache.lucene.search.Query;   
  16. import org.apache.lucene.search.Sort;   
  17. import org.apache.lucene.search.highlight.Highlighter;   
  18. import org.apache.lucene.search.highlight.QueryScorer;   
  19. import org.apache.lucene.search.highlight.SimpleFragmenter;   
  20. import org.apache.lucene.search.highlight.SimpleHTMLFormatter;   
  21.   
  22. import com.zly.test.entity.SearchResultBean;   
  23.   
  24. public class IndexSearchUtil {   
  25.        
  26.     public List<SearchResultBean> getSearchResult(String searchWhich , String searchParam , int firstResult , int maxResult) throws Exception{   
  27.         //索引所在文件夹   
  28.         File indexFile = new File("c:/index/news");   
  29.         //读取索引的indexReader   
  30.         IndexReader reader = IndexReader.open(indexFile);   
  31.         //庖丁解牛分词器   
  32.         Analyzer analyzer = new PaodingAnalyzer();   
  33.         //指定对content还是title进行查询   
  34.         QueryParser parser = new QueryParser(searchWhich , analyzer);   
  35.         //创建indexSearcher   
  36.         IndexSearcher searcher  = new IndexSearcher(reader);   
  37.         //对用户的输入进行查询   
  38.         Query query = parser.parse(searchParam);   
  39.         //根据date字段进行排序,得到查询结果   
  40.         Hits hits = searcher.search(query , new Sort("date" , true));   
  41.         //创建list,将结果保存其中,以便在jsp页面中进行显示   
  42.         List<SearchResultBean> list = new ArrayList<SearchResultBean>();   
  43.         //模拟hibernate的serFirstResult和setMaxResult以便返回指定条目的结果   
  44.         for (int i = firstResult - 1; i < firstResult + maxResult - 1; i++) {   
  45.             Document doc = hits.doc(i);   
  46.             //取得该条索引文档   
  47.             SearchResultBean srb = new SearchResultBean();   
  48.             //从中取出标题   
  49.             String title = doc.get("title");   
  50.             //从中取出内容   
  51.             String content = doc.get("content");   
  52.             //从中取出主键id   
  53.             String id = doc.get("id");   
  54.             //从中取出发布时间   
  55.             String date = doc.get("date");   
  56.             //高亮htmlFormatter对象   
  57.             SimpleHTMLFormatter sHtmlF = new SimpleHTMLFormatter("<b><font color='red'>""</font></b>");   
  58.             //高亮对象   
  59.             Highlighter highlighter = new Highlighter(sHtmlF,new QueryScorer(query));   
  60.             //设置高亮附近的字数   
  61.             highlighter.setTextFragmenter(new SimpleFragmenter(100));   
  62.             //如果查询的是标题,进行处理   
  63.             if(searchWhich.equals("title")) {   
  64.                 String bestFragment = highlighter.getBestFragment(analyzer,searchWhich,title);   
  65.                 //获得高亮后的标题内容   
  66.                 srb.setTitle(bestFragment);   
  67.                 //如果内容不足150个字,全部设置   
  68.                 if(content.length() < 150) {   
  69.                     srb.setContent(content);   
  70.                 }else {   
  71.                     //如果内容多于150个字,只取出前面150个字   
  72.                     srb.setContent(content.substring(0 , 150));   
  73.                 }   
  74.             } else {   
  75.                 //如果查询的是内容字段   
  76.                 String bestFragment = highlighter.getBestFragment(analyzer,searchWhich,content);   
  77.                 //取得高亮内容并设置   
  78.                 srb.setContent(bestFragment);   
  79.                 //设置标题,全部设置   
  80.                 srb.setTitle(title);   
  81.             }   
  82.             //设置日期   
  83.             srb.setDate(date);   
  84.             //设置主键   
  85.             srb.setId(id);   
  86.             //添加到list中,以便在jsp页面上显示   
  87.             list.add(srb);   
  88.         }   
  89.         return list;   
  90.     }   
  91.     //取得符合搜索条件的所有记录总数,以便分页 , 与上面方法类似   
  92.     public int getResultCount(String searchWhich , String searchParam) throws Exception {   
  93.         File indexFile = new File("c:/index/news");   
  94.         IndexReader reader = IndexReader.open(indexFile);   
  95.         Analyzer analyzer = new PaodingAnalyzer();   
  96.         QueryParser parser = new QueryParser(searchWhich , analyzer);   
  97.         IndexSearcher searcher  = new IndexSearcher(reader);   
  98.         Query query = parser.parse(searchParam);   
  99.         Hits hits = searcher.search(query);   
  100.         return hits.length();   
  101.     }   
  102. }  

 

 

分页action代码如下:

Java代码   复制代码  收藏代码
  1. package com.zly.test.action;   
  2.   
  3. import java.util.List;   
  4.   
  5. import com.zly.indexManager.IndexSearchUtil;   
  6. import com.zly.test.entity.PageControl;   
  7. import com.zly.test.entity.SearchResultBean;   
  8.   
  9. public class SearchAction extends BaseAction {   
  10.   
  11.        
  12.     private static final long serialVersionUID = -2387037924517370511L;   
  13.     //查询索引实体类   
  14.     private IndexSearchUtil indexSearcher;   
  15.     //对应搜索字段是标题还是内容   
  16.     private String searchWhich;   
  17.     //对应用户输入的搜索内容   
  18.     private String searchParam;   
  19.     //对应分页跳转到的页面   
  20.     private String jumpPage;   
  21.        
  22.     public String getJumpPage() {   
  23.         return jumpPage;   
  24.     }   
  25.   
  26.     public void setJumpPage(String jumpPage) {   
  27.         this.jumpPage = jumpPage;   
  28.     }   
  29.   
  30.     public String getSearchWhich() {   
  31.         return searchWhich;   
  32.     }   
  33.   
  34.     public void setSearchWhich(String searchWhich) {   
  35.         this.searchWhich = searchWhich;   
  36.     }   
  37.   
  38.     public String getSearchParam() {   
  39.         return searchParam;   
  40.     }   
  41.   
  42.     public void setSearchParam(String searchParam) {   
  43.         this.searchParam = searchParam;   
  44.     }   
  45.   
  46.     public String search() throws Exception {   
  47.         //如果为空,说明第一次进入分页   
  48.         if(jumpPage == null) {   
  49.             jumpPage = "1";   
  50.         }   
  51.         //从request范围内取得pageControl对象   
  52.         PageControl pageControl  = (PageControl) this.getRequest().getAttribute("pageControl");   
  53.         //如果为空,则是第一次分页,创建分页对象,并且设置总的记录条数,以便设置最大页数    
  54.         if(pageControl == null) {   
  55.             pageControl = new PageControl();   
  56.             pageControl.setMaxRowCount((long)indexSearcher.getResultCount(searchWhich, searchParam));   
  57.             pageControl.countMaxPage();   
  58.         }   
  59.         //设置当前页   
  60.         pageControl.setCurPage(Integer.parseInt(jumpPage));   
  61.         //计算firstResult   
  62.         int firstResult = (pageControl.getCurPage() - 1) * pageControl.getRowsPerPage() + 1;   
  63.         //计算从当前条数算还有多少条记录   
  64.         long left = pageControl.getMaxRowCount() - firstResult;   
  65.         int maxResult = -1;   
  66.         //如果剩余的记录数不如每页显示数,就设置maxResult为剩余条数   
  67.         if(left < pageControl.getRowsPerPage()) {   
  68.             maxResult = Integer.valueOf(left + "");   
  69.         //如果剩余记录数大于每页显示页数,就设置maxResult为每页条数   
  70.         }else {   
  71.             maxResult = pageControl.getRowsPerPage();    
  72.         }   
  73.         //取得查询结果集   
  74.         List<SearchResultBean> userList = indexSearcher.getSearchResult(searchWhich, searchParam, firstResult, maxResult);   
  75.         //设置为pageControl   
  76.         pageControl.setData(userList);   
  77.         //将pageControl设置到request范围,以便在jsp现实结果   
  78.         this.getRequest().setAttribute("pageControl", pageControl);   
  79.         //将searchWhich和searchParam设置到request范围,以便添加到分页jsp的form里面的hidden表单域,以便下次分页时,能够将值提交过来   
  80.         this.getRequest().setAttribute("searchWhich", searchWhich);   
  81.         this.getRequest().setAttribute("searchParam", searchParam);   
  82.         //跳转到分页视图   
  83.         return SUCCESS;   
  84.            
  85.     }   
  86.   
  87.     public IndexSearchUtil getIndexSearcher() {   
  88.         return indexSearcher;   
  89.     }   
  90.   
  91.     public void setIndexSearcher(IndexSearchUtil indexSearcher) {   
  92.         this.indexSearcher = indexSearcher;   
  93.     }   
  94.        
  95. }  

 

 

搜索的action在struts.xml中设置如下:

 

Xml代码   复制代码  收藏代码
  1. <action name="searchAction" class="searchAction" method="search">  
  2.     <result>/searchResult.jsp</result>  
  3. </action>  

 

//searchResult.jsp代码如下:

 

Html代码   复制代码  收藏代码
  1. <%@ page language="java" contentType="text/html;charset=utf-8"  
  2.     pageEncoding="utf-8"%>  
  3. <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>  
  4. <%@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>  
  5. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">  
  6. <html>  
  7. <head>  
  8. <meta http-equiv="Content-Type" content="text/html; charset=utf-8">  
  9. <title>${searchParam} 的搜查结果 -- 最快新闻网</title>  
  10. </head>  
  11. <body>  
  12.     <jsp:include page="index.jsp"></jsp:include>  
  13.     <div id="content">  
  14.            
  15.         <div id="searchResults" >  
  16.             <c:forEach items="${pageControl.data}" var="result">  
  17.                 <div style="margin-top: 20px;">  
  18.                     <span>  
  19.                         <a href="detailAction.action?id=${result.id }">${result.title}</a><br />  
  20.                         ${result.content }   
  21.                         <font color="green">http://localhost:8080/NewsWithSearch/detailAction.action?id=${result.id } ${result.date }</font>  
  22.                     </span>  
  23.                     <br />  
  24.                 </div>  
  25.             </c:forEach>         
  26.         </div>  
  27.            
  28.         <br /><br /><br /><br />  
  29.            
  30.         <%@ include file="searchPage.jsp" %>  
  31.     </div>  
  32. </body>  
  33. </html>  

原文地址:http://shuaigg-babysky.iteye.com/blog/414477

猜你喜欢

转载自he3109006290.iteye.com/blog/2051399
今日推荐