- 浏览: 680708 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (302)
- 知识库 (51)
- lucene (8)
- 数据结构 (7)
- 问题及解决方法 (97)
- Quartz (4)
- JavaScript (26)
- java 基础 (40)
- 休闲 (9)
- 数据库相关 (32)
- 面试题 (4)
- Hibernate (5)
- Struts (11)
- JBPM (2)
- Spring (3)
- ajax (7)
- Flex (0)
- 报表 (4)
- 打印 (2)
- prototype (3)
- Struts2 (3)
- JQUERY (4)
- Ruby (0)
- Linux (9)
- Android (3)
- Objective-c (2)
- Python (8)
- map (1)
- mybatis (3)
- php (2)
- ios (0)
- 问题及解决方法 struts2 spring ognl resion tomcat (0)
- 问题及解决方法 struts2 spring ognl resin tomcat (1)
- c++ (2)
- 问题及解决方法 upload.parseRequest(request) 为空 (1)
- Eclipse maven tomcat (1)
- 知识库 服务器配置 (1)
- sersync2 (1)
- Maven Jetty Plugin 配置指南(翻译) (1)
最新评论
-
jgroups:
...
遇到Causedby:java.lang.NoClassDefFoundError:javax/validation/ParameterNameProvider -
dmyccc:
第二种方法还是很佩服楼主的,但是多少感觉有点投机取巧了。但是确 ...
spring mvc整合kindeditor文件上传问题 -
du_bo:
在xx-servlet.xml中这样配置<bean id ...
spring mvc整合kindeditor文件上传问题 -
java梦之翼:
太感谢了, 问题得到解决, 感谢
异常org.mybatis.spring.transaction.SpringManagedTransactionFactory.newTransaction -
du_bo:
这是我的上传package com.sp.controller ...
spring mvc整合kindeditor文件上传问题
目标:创建一个具有高度可移植的,定时创建索引的站内搜索。
途径:dic和index都放到程序中去。
准备:
1 Lucene
Lucene Java(以下简称Lucene)目前可用版本是2.4.0,关于Lucene的详细信息请查看http://lucene.apache.org/java/docs/index.html。
2 Paoding
Qieqie同学的伟大作品、优秀的Lucene中文分词组件,目前的版本为paoding-analysis-2.0.4-beta,对应的Lucene的版本为2.2。关于Paoding的具体信息请查看http://code.google.com/p/paoding/。
3 下载最新的paoding-analysis-2.0.4-beta版本(里面包含了lucene-core-2.2.0.jar, lucene-analyzers-2.2.0.jar,lucene-highlighter-2.2.0.jar, junit.jar, commons-logging.jar)。
>>>>> 本文为原创,需要转载的朋友请注明: http://jnotnull.iteye.com 谢谢支持!<<<<<
开始工作:
1 试运行
打开下载包中的examples文件夹,运行一下吧(注意一下编码)。
2 集成到SSH2系统中去 (系统结构Action->service->dao)
1) 由于SSH2系统是web系统,因此在配置Paoding上就有可能和第一步有些不同。
直接把paoding文件夹下的src文件夹下的所有文件和dic文件夹复制到你的项目中去。打开paoding-dic-home.properties文件,修改paoding.dic.home.config-fisrt=this,使得程序知道该配置文件,修改paoding.dic.home=classpath:dic,使得字典在该项目中。保存就可以了。在这里我使用了classpath:dic是为了增加可移植性。如果使用绝对路径没有什么可说的了,但是如果你是制定为classpath:dic,则需要修改一下Paoding中的代码了。找到PaodingMaker.java的setDicHomeProperties方法,修改File dicHomeFile = getFile(dicHome);为
- File dicHomeFile2 = getFile(dicHome);
- String path="";
- try {
- path = URLDecoder.decode(dicHomeFile2.getPath(),"UTF-8");
- } catch (UnsupportedEncodingException e) {
- e.printStackTrace();
- }
- File dicHomeFile = new File(path);
File dicHomeFile2 = getFile(dicHome); String path=""; try { path = URLDecoder.decode(dicHomeFile2.getPath(),"UTF-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } File dicHomeFile = new File(path);
目的是解码,不然如果你的词典路径中有空格和汉字会出现找不到字典的异常。
2)表结构
- CREATE TABLE `news` (
- `id` int(11) NOT NULL auto_increment,
- `title` varchar(255) default NULL,
- `details` mediumtext,
- `author` varchar(255) default NULL,
- `publisher` varchar(100) default NULL,
- `clicks` int(11) default NULL,
- `source` varchar(255) default NULL,
- `addtime` datetime default NULL,
- ` category ` varchar(100) default NULL,
- `keywords` varchar(255) default NULL,
- PRIMARY KEY (`id`)
- ) ENGINE=InnoDB DEFAULT CHARSET=gbk;
3 正式实施编码 编写站内搜索分为两步:创建索引和进行搜索,所需类:SearchAction.java和TaskAction.java(同一目录) 1) 创建索引 主要任务:从已有的txt文件中读取上一次进行索引的最后一条新闻的id号,然后从业务逻辑中查找大于这个id号的所有新闻进行索引,最后把这次最后的一条新闻id写入txt文件中。在这里要处理好路径的问题。在这里所有的记录id号的txt文件都放到了action目录下面。 新建TaskAction,增加如下方法
- public void createIndex() {
- String path;
- try {
- //两个参数:创建索引的位置 和 上一次创建索引最后的新闻id所在文件
- createNewsIndex(getPath(TaskAction.class, "date/index/news"),"newsid.txt");
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- public String getPath(Class clazz, String textName)
- throws IOException {
- String path = (URLDecoder.decode(
- clazz.getResource(textName).toString(), "UTF-8")).substring(6);
- return path;
- }
- public void createNewsIndex(String path,String textName) throws Exception {
- String newsId = "0";
- newsId = readText(TaskAction.class, textName);
- if (null ==newsId || "".equals(newsId))
- newsId = "0";
- // 使用paoding中文分析器
- Analyzer analyzer = new PaodingAnalyzer();
- FSDirectory directory = FSDirectory.getDirectory(path);
- System.out.println(directory.toString());
- IndexWriter writer = new IndexWriter(directory, analyzer, isEmpty(TaskAction.class, textName));
- Document doc = new Document();
- // 从业务逻辑层读取大于当前id的信息
- List list = newsManageService.getNewsBigId(Integer.parseInt(newsId));
- Iterator iterator = list.iterator();
- News news = new News();
- while (iterator.hasNext()) {
- doc = new Document();
- news = (News) iterator.next();
- doc.add(new Field("id", "" + news.getId(), Field.Store.YES,
- Field.Index.UN_TOKENIZED));
- doc.add(new Field("title", "" + news.getTitle(), Field.Store.YES,
- Field.Index.TOKENIZED));
- doc.add(new Field("author", "" + news.getAuthor(), Field.Store.YES,
- Field.Index.TOKENIZED));
- doc.add(new Field("details", ""
- + Constants.splitAndFilterString(news.getDetails()),
- Field.Store.YES, Field.Index.TOKENIZED,
- Field.TermVector.WITH_POSITIONS_OFFSETS));
- doc.add(new Field("addtime", "" + news.getAddtime(),
- Field.Store.YES, Field.Index.TOKENIZED));
- doc.add(new Field("keywords", "" + news.getKeywords(),
- Field.Store.YES, Field.Index.TOKENIZED));
- System.out.println("Indexing file " + news.getName() + "...");
- articleId = String.valueOf(news.getId());
- try {
- writer.addDocument(doc);
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- // 优化并关闭
- writer.optimize();
- writer.close();
- // 将我索引的最后一篇文章的id写入文件
- String content = WriteText(TaskAction.class,
- textName, newsId);
- }
- public boolean isEmpty(Class clazz, String textName) throws Exception {
- String articleId = "0";
- boolean isEmpty = true;
- articleId = ContentReader.readText(clazz, textName);
- if (null == articleId || "".equals(articleId))
- articleId = "0";
- if (!articleId.equals("0"))
- isEmpty = false;
- System.out.println(clazz.getName()+" "+isEmpty);
- return isEmpty;
- }
- //该方法参考了paoding中example中的一个方法。
- public String readText(Class clazz, String textName)
- throws IOException {
- InputStream in = clazz.getResourceAsStream(textName);
- Reader re = new InputStreamReader(in, "UTF-8");
- char[] chs = new char[1024];
- int count;
- String content = "";
- while ((count = re.read(chs)) != -1) {
- content = content + new String(chs, 0, count);
- }
- return content;
- }
- public String WriteText(Class clazz, String textName, String text)
- throws IOException {
- String path = (URLDecoder.decode(
- clazz.getResource(textName).toString(), "UTF-8")).substring(6);
- System.out.println(path);
- File file = new File(path);
- BufferedWriter bw = new BufferedWriter(new FileWriter(file));
- String temp = text;
- bw.write(temp);
- bw.close();
- return temp;
- }
2)进行搜索
- public void searchIndex(String path, String keywords) throws Exception {
- String[] FIELD = { "title", "details" };
- String QUERY = keywords;
- Analyzer analyzer = new PaodingAnalyzer();
- FSDirectory directory = FSDirectory.getDirectory(path);
- IndexReader reader = IndexReader.open(directory);
- String queryString = QUERY;
- BooleanClause.Occur[] flags = new BooleanClause.Occur[] {
- BooleanClause.Occur.SHOULD, BooleanClause.Occur.SHOULD };
- Query query = MultiFieldQueryParser.parse(queryString, FIELD, flags,
- analyzer);
- Searcher searcher = new IndexSearcher(directory);
- query = query.rewrite(reader);
- System.out.println("Searching for: " + query.toString());
- Hits hits = searcher.search(query);
- NewsDTO news = new NewsDTO();
- String highLightText = "";
- for (int i = 0; i < hits.length(); i++) {
- Document doc = hits.doc(i);
- String title1 = doc.get("title");
- String contents1 = doc.get("details");
- SimpleHTMLFormatter simpleHTMLFormatter = new SimpleHTMLFormatter(
- "", "");
- Highlighter highlighter = new Highlighter(simpleHTMLFormatter,
- new QueryScorer(query));
- highlighter.setTextFragmenter(new SimpleFragmenter(200));
- if (contents1 != null) {
- TokenStream tokenStream = analyzer.tokenStream("details",
- new StringReader(contents1));
- highLightText = highlighter.getBestFragment(tokenStream,
- contents1);
- }
- news = new NewsDTO();
- news.setId(Integer.parseInt(doc.get("id")));
- news.setName(doc.get("title"));
- news.setDetails(highLightText);
- news.setAddtime(doc.get("addtime"));
- news.setAuthor(doc.get("author"));
- searchResultItem.add(news);
- }
- reader.close();
- }
核心代码已经基本完成了,还有一个加亮显示,非常不错的哦。
3)再来一个定时创建索引:
定义一下bean
- <bean id="myTask" class="edu.cumt.jnotnull.action.TaskAction">
- <property name="newsManageService">
- <ref bean="newsManageService" />
- </property>
- </bean>
- <bean id="entity"
- class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
- <property name="targetObject">
- <ref local="myTask" />
- </property>
- <property name="targetMethod">
- <value>createIndex</value>
- </property>
- </bean>
- <bean id="cron"
- class="org.springframework.scheduling.quartz.CronTriggerBean">
- <property name="jobDetail">
- <ref bean="entity" />
- </property>
- <property name="cronExpression">
- <value>0 0-5 2 * * ?</value>
- </property>
- </bean>
- <bean autowire="no"
- class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
- <property name="triggers">
- <list>
- <ref local="cron" />
- </list>
- </property>
- </bean>
这样就可以在夜里面让他自动促发了。
发表评论
-
Lucene 索引架构及建立、删除索引
2009-09-25 11:25 1373深入 lucene 索引机制 ... -
简介Lucene2.0中Query
2009-01-05 11:36 1516基本流程1、 初始化IndexSearcher :Search ... -
lucene学习笔记 高级篇
2009-01-05 10:30 1302一、环境 需要导入lucene.jar包(在lucene.ap ... -
Lucene索引查询分页实例
2008-12-16 18:18 2758一、输入关键字的lucene.html<html> ... -
lucene 的基本概念
2008-12-03 16:11 15211 lucene简介1.1 什么是luceneLucene是一 ... -
Lucene-2.0学习文档
2008-12-03 15:41 1126Lucene-2.0学习文档 Lucene是apache组织 ... -
用Lucene检索数据库
2008-12-03 14:55 4562用Lucene检索数据库 By kevinwu on Mar ...
相关推荐
Lucene提供了一套API用于解析、过滤、分析文件并构建和使用索引。开发者可以将Lucene视为支持全文索引的数据库系统。 - **Compass**:Compass被定义为面向域模型的搜索框架,这意味着它必须支持对象搜索、持久化...
下面是一个基于SSH(Struts2+Spring+Hibernate)架构的Compass使用示例: 1. **添加依赖库**:在SSH项目基础上添加Compass及相关依赖库,具体包括: - `compass-2.1.2.jar` - `compass-index-patch.jar` - `...
WebSocket4J 是一个用 Java 实现的 WebSocket 协议的类库,可使用 Java 来构建交互式 Web 应用。WebSocket4J 并未实现客户端通讯协议,所以不能用它来连接 WebSocket 服务器。 Struts验证码插件 JCaptcha4Struts2 ...
WebSocket4J 是一个用 Java 实现的 WebSocket 协议的类库,可使用 Java 来构建交互式 Web 应用。WebSocket4J 并未实现客户端通讯协议,所以不能用它来连接 WebSocket 服务器。 Struts验证码插件 JCaptcha4Struts2 ...
WebSocket4J 是一个用 Java 实现的 WebSocket 协议的类库,可使用 Java 来构建交互式 Web 应用。WebSocket4J 并未实现客户端通讯协议,所以不能用它来连接 WebSocket 服务器。 Struts验证码插件 JCaptcha4Struts2 ...
WebSocket4J 是一个用 Java 实现的 WebSocket 协议的类库,可使用 Java 来构建交互式 Web 应用。WebSocket4J 并未实现客户端通讯协议,所以不能用它来连接 WebSocket 服务器。 Struts验证码插件 JCaptcha4Struts2 ...
WebSocket4J 是一个用 Java 实现的 WebSocket 协议的类库,可使用 Java 来构建交互式 Web 应用。WebSocket4J 并未实现客户端通讯协议,所以不能用它来连接 WebSocket 服务器。 Struts验证码插件 JCaptcha4Struts2 ...
WebSocket4J 是一个用 Java 实现的 WebSocket 协议的类库,可使用 Java 来构建交互式 Web 应用。WebSocket4J 并未实现客户端通讯协议,所以不能用它来连接 WebSocket 服务器。 Struts验证码插件 JCaptcha4Struts2 ...
WebSocket4J 是一个用 Java 实现的 WebSocket 协议的类库,可使用 Java 来构建交互式 Web 应用。WebSocket4J 并未实现客户端通讯协议,所以不能用它来连接 WebSocket 服务器。 Struts验证码插件 JCaptcha4Struts2 ...
WebSocket4J 是一个用 Java 实现的 WebSocket 协议的类库,可使用 Java 来构建交互式 Web 应用。WebSocket4J 并未实现客户端通讯协议,所以不能用它来连接 WebSocket 服务器。 Struts验证码插件 JCaptcha4Struts2 ...
WebSocket4J 是一个用 Java 实现的 WebSocket 协议的类库,可使用 Java 来构建交互式 Web 应用。WebSocket4J 并未实现客户端通讯协议,所以不能用它来连接 WebSocket 服务器。 Struts验证码插件 JCaptcha4Struts2 ...
WebSocket4J 是一个用 Java 实现的 WebSocket 协议的类库,可使用 Java 来构建交互式 Web 应用。WebSocket4J 并未实现客户端通讯协议,所以不能用它来连接 WebSocket 服务器。 Struts验证码插件 JCaptcha4Struts2 ...
WebSocket4J 是一个用 Java 实现的 WebSocket 协议的类库,可使用 Java 来构建交互式 Web 应用。WebSocket4J 并未实现客户端通讯协议,所以不能用它来连接 WebSocket 服务器。 Struts验证码插件 JCaptcha4Struts2 ...
WebSocket4J 是一个用 Java 实现的 WebSocket 协议的类库,可使用 Java 来构建交互式 Web 应用。WebSocket4J 并未实现客户端通讯协议,所以不能用它来连接 WebSocket 服务器。 Struts验证码插件 JCaptcha4Struts2 ...
WebSocket4J 是一个用 Java 实现的 WebSocket 协议的类库,可使用 Java 来构建交互式 Web 应用。WebSocket4J 并未实现客户端通讯协议,所以不能用它来连接 WebSocket 服务器。 Struts验证码插件 JCaptcha4Struts2 ...