一、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
- package com.zly.indexManager;
- import java.io.File;
- import java.text.DateFormat;
- import java.text.SimpleDateFormat;
- import java.util.List;
- import net.paoding.analysis.analyzer.PaodingAnalyzer;
- import org.apache.lucene.analysis.Analyzer;
- import org.apache.lucene.document.Document;
- import org.apache.lucene.document.Field;
- import org.apache.lucene.index.IndexWriter;
- import org.hibernate.SessionFactory;
- import org.hibernate.cfg.AnnotationConfiguration;
- import org.hibernate.cfg.Configuration;
- import org.hibernate.Session;
- import org.htmlparser.Parser;
- import com.zly.test.entity.NewsItem;
- public class IndexCreateUtil {
- @SuppressWarnings("unchecked")
- public void createIndexForNews() throws Exception {
- //存放索引的文件夹
- File indexFile = new File("c:/index/news");
- //使用了庖丁解牛分词器
- Analyzer analyzer = new PaodingAnalyzer();
- //使用索引文件夹,庖丁解牛分词器创建IndexWriter
- IndexWriter indexWriter = new IndexWriter(indexFile , analyzer , true);
- //从数据库中读取出所有的新闻记录以便进行索引的创建
- Configuration cfg = new AnnotationConfiguration().configure();
- SessionFactory factory = cfg.buildSessionFactory();
- Session session = factory.openSession();
- List<NewsItem> list = session.createQuery(" from NewsItem").list();
- DateFormat format = new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒");
- //对所有的新闻实体进行索引创建
- for (NewsItem newsItem : list) {
- //建立一个lucene文档
- Document doc = new Document();
- //得到新闻标题
- String newsTitle = newsItem.getNewsTitle();
- //得到新闻内容
- String newsContent = newsItem.getNewsContent();
- //得到新闻事件
- String publishDate = format.format(newsItem.getPublishTime());
- //得到新闻主键id
- String id = newsItem.getId() + "";
- //将新闻标题加入文档,因为要搜索和高亮,所以index是tokennized,TermVector是WITH_POSITIONS_OFFSETS
- doc.add(new Field("title" , newsTitle , Field.Store.YES , Field.Index.TOKENIZED , Field.TermVector.WITH_POSITIONS_OFFSETS));
- //利用htmlparser得到新闻内容html的纯文本
- Parser parser = new Parser();
- parser.setInputHTML(newsContent);
- String strings = parser.parse(null).elementAt(0).toPlainTextString().trim();
- //添加新闻内容至文档,与标题相似
- doc.add(new Field("content" , strings , Field.Store.COMPRESS , Field.Index.TOKENIZED , Field.TermVector.WITH_POSITIONS_OFFSETS));
- //添加时间至文档,因为要按照此字段降序排列排序,所以tokenzied,不用高亮所以TermVector是no就行了
- doc.add(new Field("date" , publishDate , Field.Store.YES , Field.Index.TOKENIZED , Field.TermVector.NO));
- //添加主键至文档,不分词,不高亮。
- doc.add(new Field("id" , id , Field.Store.YES , Field.Index.NO , Field.TermVector.NO));
- indexWriter.addDocument(doc);
- }
- //创建索引
- indexWriter.optimize();
- indexWriter.close();
- //关闭session
- session.close();
- }
- public static void main(String[] args) throws Exception {
- IndexCreateUtil util = new IndexCreateUtil();
- util.createIndexForNews();
- }
- }
对索引进行搜索的代码如下:
- package com.zly.indexManager;
- import java.io.File;
- import java.util.ArrayList;
- import java.util.List;
- import net.paoding.analysis.analyzer.PaodingAnalyzer;
- import org.apache.lucene.analysis.Analyzer;
- import org.apache.lucene.document.Document;
- import org.apache.lucene.index.IndexReader;
- import org.apache.lucene.queryParser.QueryParser;
- import org.apache.lucene.search.Hits;
- import org.apache.lucene.search.IndexSearcher;
- import org.apache.lucene.search.Query;
- import org.apache.lucene.search.Sort;
- import org.apache.lucene.search.highlight.Highlighter;
- import org.apache.lucene.search.highlight.QueryScorer;
- import org.apache.lucene.search.highlight.SimpleFragmenter;
- import org.apache.lucene.search.highlight.SimpleHTMLFormatter;
- import com.zly.test.entity.SearchResultBean;
- public class IndexSearchUtil {
- public List<SearchResultBean> getSearchResult(String searchWhich , String searchParam , int firstResult , int maxResult) throws Exception{
- //索引所在文件夹
- File indexFile = new File("c:/index/news");
- //读取索引的indexReader
- IndexReader reader = IndexReader.open(indexFile);
- //庖丁解牛分词器
- Analyzer analyzer = new PaodingAnalyzer();
- //指定对content还是title进行查询
- QueryParser parser = new QueryParser(searchWhich , analyzer);
- //创建indexSearcher
- IndexSearcher searcher = new IndexSearcher(reader);
- //对用户的输入进行查询
- Query query = parser.parse(searchParam);
- //根据date字段进行排序,得到查询结果
- Hits hits = searcher.search(query , new Sort("date" , true));
- //创建list,将结果保存其中,以便在jsp页面中进行显示
- List<SearchResultBean> list = new ArrayList<SearchResultBean>();
- //模拟hibernate的serFirstResult和setMaxResult以便返回指定条目的结果
- for (int i = firstResult - 1; i < firstResult + maxResult - 1; i++) {
- Document doc = hits.doc(i);
- //取得该条索引文档
- SearchResultBean srb = new SearchResultBean();
- //从中取出标题
- String title = doc.get("title");
- //从中取出内容
- String content = doc.get("content");
- //从中取出主键id
- String id = doc.get("id");
- //从中取出发布时间
- String date = doc.get("date");
- //高亮htmlFormatter对象
- SimpleHTMLFormatter sHtmlF = new SimpleHTMLFormatter("<b><font color='red'>", "</font></b>");
- //高亮对象
- Highlighter highlighter = new Highlighter(sHtmlF,new QueryScorer(query));
- //设置高亮附近的字数
- highlighter.setTextFragmenter(new SimpleFragmenter(100));
- //如果查询的是标题,进行处理
- if(searchWhich.equals("title")) {
- String bestFragment = highlighter.getBestFragment(analyzer,searchWhich,title);
- //获得高亮后的标题内容
- srb.setTitle(bestFragment);
- //如果内容不足150个字,全部设置
- if(content.length() < 150) {
- srb.setContent(content);
- }else {
- //如果内容多于150个字,只取出前面150个字
- srb.setContent(content.substring(0 , 150));
- }
- } else {
- //如果查询的是内容字段
- String bestFragment = highlighter.getBestFragment(analyzer,searchWhich,content);
- //取得高亮内容并设置
- srb.setContent(bestFragment);
- //设置标题,全部设置
- srb.setTitle(title);
- }
- //设置日期
- srb.setDate(date);
- //设置主键
- srb.setId(id);
- //添加到list中,以便在jsp页面上显示
- list.add(srb);
- }
- return list;
- }
- //取得符合搜索条件的所有记录总数,以便分页 , 与上面方法类似
- public int getResultCount(String searchWhich , String searchParam) throws Exception {
- File indexFile = new File("c:/index/news");
- IndexReader reader = IndexReader.open(indexFile);
- Analyzer analyzer = new PaodingAnalyzer();
- QueryParser parser = new QueryParser(searchWhich , analyzer);
- IndexSearcher searcher = new IndexSearcher(reader);
- Query query = parser.parse(searchParam);
- Hits hits = searcher.search(query);
- return hits.length();
- }
- }
分页action代码如下:
- package com.zly.test.action;
- import java.util.List;
- import com.zly.indexManager.IndexSearchUtil;
- import com.zly.test.entity.PageControl;
- import com.zly.test.entity.SearchResultBean;
- public class SearchAction extends BaseAction {
- private static final long serialVersionUID = -2387037924517370511L;
- //查询索引实体类
- private IndexSearchUtil indexSearcher;
- //对应搜索字段是标题还是内容
- private String searchWhich;
- //对应用户输入的搜索内容
- private String searchParam;
- //对应分页跳转到的页面
- private String jumpPage;
- public String getJumpPage() {
- return jumpPage;
- }
- public void setJumpPage(String jumpPage) {
- this.jumpPage = jumpPage;
- }
- public String getSearchWhich() {
- return searchWhich;
- }
- public void setSearchWhich(String searchWhich) {
- this.searchWhich = searchWhich;
- }
- public String getSearchParam() {
- return searchParam;
- }
- public void setSearchParam(String searchParam) {
- this.searchParam = searchParam;
- }
- public String search() throws Exception {
- //如果为空,说明第一次进入分页
- if(jumpPage == null) {
- jumpPage = "1";
- }
- //从request范围内取得pageControl对象
- PageControl pageControl = (PageControl) this.getRequest().getAttribute("pageControl");
- //如果为空,则是第一次分页,创建分页对象,并且设置总的记录条数,以便设置最大页数
- if(pageControl == null) {
- pageControl = new PageControl();
- pageControl.setMaxRowCount((long)indexSearcher.getResultCount(searchWhich, searchParam));
- pageControl.countMaxPage();
- }
- //设置当前页
- pageControl.setCurPage(Integer.parseInt(jumpPage));
- //计算firstResult
- int firstResult = (pageControl.getCurPage() - 1) * pageControl.getRowsPerPage() + 1;
- //计算从当前条数算还有多少条记录
- long left = pageControl.getMaxRowCount() - firstResult;
- int maxResult = -1;
- //如果剩余的记录数不如每页显示数,就设置maxResult为剩余条数
- if(left < pageControl.getRowsPerPage()) {
- maxResult = Integer.valueOf(left + "");
- //如果剩余记录数大于每页显示页数,就设置maxResult为每页条数
- }else {
- maxResult = pageControl.getRowsPerPage();
- }
- //取得查询结果集
- List<SearchResultBean> userList = indexSearcher.getSearchResult(searchWhich, searchParam, firstResult, maxResult);
- //设置为pageControl
- pageControl.setData(userList);
- //将pageControl设置到request范围,以便在jsp现实结果
- this.getRequest().setAttribute("pageControl", pageControl);
- //将searchWhich和searchParam设置到request范围,以便添加到分页jsp的form里面的hidden表单域,以便下次分页时,能够将值提交过来
- this.getRequest().setAttribute("searchWhich", searchWhich);
- this.getRequest().setAttribute("searchParam", searchParam);
- //跳转到分页视图
- return SUCCESS;
- }
- public IndexSearchUtil getIndexSearcher() {
- return indexSearcher;
- }
- public void setIndexSearcher(IndexSearchUtil indexSearcher) {
- this.indexSearcher = indexSearcher;
- }
- }
搜索的action在struts.xml中设置如下:
- <action name="searchAction" class="searchAction" method="search">
- <result>/searchResult.jsp</result>
- </action>
//searchResult.jsp代码如下:
- <%@ page language="java" contentType="text/html;charset=utf-8"
- pageEncoding="utf-8"%>
- <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
- <%@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
- <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
- <html>
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
- <title>${searchParam} 的搜查结果 -- 最快新闻网</title>
- </head>
- <body>
- <jsp:include page="index.jsp"></jsp:include>
- <div id="content">
- <div id="searchResults" >
- <c:forEach items="${pageControl.data}" var="result">
- <div style="margin-top: 20px;">
- <span>
- <a href="detailAction.action?id=${result.id }">${result.title}</a><br />
- ${result.content }
- <font color="green">http://localhost:8080/NewsWithSearch/detailAction.action?id=${result.id } ${result.date }</font>
- </span>
- <br />
- </div>
- </c:forEach>
- </div>
- <br /><br /><br /><br />
- <%@ include file="searchPage.jsp" %>
- </div>
- </body>
- </html>
相关推荐
通过上述方法,不仅能够保持Lucene高亮显示功能的准确性,还能在处理中文分词时显著提升系统性能,特别是对于大数据量和高并发场景下的应用,这种优化显得尤为重要。Lucene的TermVector特性,配合合理的代码实现,为...
### Lucene高亮显示详解 在全文搜索领域,Apache Lucene是业界标准的搜索引擎库,提供了强大的文本搜索功能。而在搜索结果中实现关键词高亮显示,可以极大地提升用户体验,让用户快速定位到搜索词所在的位置。本文...
lucene-highlighter-3.5.0.jar lucene高亮包
**SpringBoot+Lucene搜索结果高亮显示** 在现代Web应用程序中,强大的全文搜索引擎功能是不可或缺的,而Apache Lucene正是这样一个高效的、可扩展的开源全文检索库。在这个SpringBoot+Lucene的Demo中,我们将深入...
lucene3.5高亮
本文将详细介绍如何使用Java和Lucene来实现HTML文本的高亮显示,以便用户在搜索结果中能快速识别关键词。提供的`HighLighterUtils.java`文件应该包含了实现这一功能的核心代码。 首先,我们需要理解高亮显示的基本...
本话题聚焦于“Lucene多字段查询”和“文字高亮显示”,这两个特性在信息检索和数据挖掘中具有广泛应用。 首先,让我们深入理解“Lucene多字段查询”。在信息检索系统中,用户可能希望根据多个字段来过滤和排序结果...
《Lucene+HighLighter高亮显示实例解析》 在信息技术领域,搜索引擎的构建与优化是至关重要的一环,其中,如何有效地对搜索结果进行高亮显示,以突出关键信息,是提升用户体验的关键因素之一。本篇文章将深入探讨...
《深入解析Lucene高亮显示源码:剖析`lucene-highlighter-2.2.0-src.zip`》 Lucene,作为一个开源全文检索库,以其高效、灵活的特点在信息检索领域广泛应用。在处理搜索结果时,为了提升用户体验,通常会采用高亮...
- **搜索结果高亮**: 为了提高用户阅读体验,Lucene 高亮包提供了搜索关键词在文档中的高亮显示功能,使用户能快速识别出匹配的关键词。 - **自定义样式**: 开发者可以自定义高亮的样式,如使用不同的颜色或者背景...
标题中的“lucene.net以及高亮的DLL文件”指的是在.NET环境中使用Lucene搜索引擎库时,涉及到了文本高亮显示的DLL组件。Lucene.Net是一个开源的全文检索库,它是Apache Lucene项目针对.NET Framework的移植版本,为...
### Lucene高亮显示实现详解 #### 一、引言 在搜索引擎开发中,为了提升用户体验,往往需要对搜索结果中的关键词进行高亮处理。这样不仅可以让用户一眼就能看到搜索结果与他们输入的关键词之间的关联性,同时也有...
**Lucene高亮显示** 在信息检索领域,用户通常希望在搜索结果中快速找到与查询相关的关键词,这就是所谓的“高亮显示”。Apache Lucene是一个强大的全文搜索引擎库,它提供了多种功能,包括高亮显示搜索结果。高亮...
例如,当用户搜索“Java GUI”时,Lucene 高亮组件会在文档中找到“Java”和“GUI”这两个词,并用特殊格式(如加粗、颜色等)标注出来。 ### 四、Java GUI 应用 在给定的文件名称“javagui”中,我们可以推测这...
本压缩包中的代码着重展示了如何使用 Lucene 进行分页搜索和结果高亮显示。下面将详细解释这两个关键知识点。 **一、Lucene 分页搜索** 在大型数据集上进行搜索时,一次性返回所有结果并不实际,因此分页搜索显得...
lucene-memory-3.0.2.jar,lucene高亮显示中不可少的jar包lucene-memory-*.jar
在Android平台上实现全文检索并高亮关键字,常常需要用到开源全文搜索引擎Lucene。Lucene是一个高性能、全文本搜索库,提供了一个简单但强大的应用编程接口(API)用于索引和搜索文本。下面我们将深入探讨如何在...
本文将深入探讨Lucene.NET如何进行中文分词以及高亮显示的实现。 ### 1. 中文分词 中文分词是将连续的汉字序列切分成具有语义的词语的过程,是自然语言处理(NLP)中的基础步骤。在Lucene.NET中,为了支持中文分词...
用于编写Lucene高亮摘要的jar包,版本2.0.0,好用。谁用谁知道~~~~
《Lucene5学习之Highlighter关键字高亮》 在信息技术领域,搜索引擎的使用已经变得无处不在,而其中的关键技术之一就是如何有效地突出显示搜索结果中的关键字,这就是我们今天要探讨的主题——Lucene5中的...