- 浏览: 1183460 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (350)
- Ajax研究 (2)
- javascript (22)
- struts (15)
- hibernate (12)
- spring (8)
- 我的生活 (28)
- jsp (2)
- 我的随笔 (84)
- 脑筋急转弯 (1)
- struts2 (2)
- ibatis (1)
- groovy (1)
- json (4)
- flex (20)
- Html Css (5)
- lucene (11)
- solr研究 (2)
- nutch (25)
- ExtJs (3)
- linux (6)
- 正则表达式 (2)
- xml (1)
- jetty (0)
- 多线程 (1)
- hadoop (40)
- mapreduce (5)
- webservice (2)
- 云计算 (8)
- 创业计划 (1)
- android (8)
- jvm内存研究 (1)
- 新闻 (2)
- JPA (1)
- 搜索技术研究 (2)
- perl (1)
- awk (1)
- hive (7)
- jvm (1)
最新评论
-
pandaball:
支持一下,心如大海
做有气质的男人 -
recall992:
山东分公司的风格[color=brown]岁的法国电视[/co ...
solr是如何存储索引的 -
zhangsasa:
-services "services-config ...
flex中endpoint的作用是什么? -
来利强:
非常感谢
java使用json所需要的几个包 -
zhanglian520:
有参考价值。
hadoop部署错误之一:java.lang.IllegalArgumentException: Wrong FS
转帖:http://jushi1988.iteye.com/blog/693188
--- 2010-06-18 17:00 代码修改: 修改重复创建索引,添加双字段高亮。
今天发一个简单的和数据库交互的Lucene示例,只是初步的靠Lucene自带的分词实现中文分词,效果肯定没有网上琳琅的分词器相媲美,只为了示例,用了自带的高亮。页面不好看,将就一下哦。
主要是由 Spring + Struts1 + Mysql 5 实现, 只是为了实现功能。请各位大侠拍砖。
好了,不多说了。贴代码:
1. T_ARTICLE 表
Java代码
DROP TABLE IF EXISTS `t_article`;
CREATE TABLE `t_article` (
`ID` varchar(32) NOT NULL default '',
`ARTICLE_TITLE` varchar(255) default NULL,
`ARTICLE_TAG` varchar(255) default NULL,
`ARTICLE_CONTENT` text,
PRIMARY KEY (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `t_article`;
CREATE TABLE `t_article` (
`ID` varchar(32) NOT NULL default '',
`ARTICLE_TITLE` varchar(255) default NULL,
`ARTICLE_TAG` varchar(255) default NULL,
`ARTICLE_CONTENT` text,
PRIMARY KEY (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8; 上面的数据 随便加一下吧,主要是article_content和article_title字段的数据,article_content是个text字段,所以你可以粘贴网页的文字内容添加到本字段中。
2.业务接口 ArticleService.java
Java代码
package com.jushi.lucene.business;
import java.util.List;
import com.jushi.lucene.entities.Article;
/**
* @Author jushi
* @CreateDate Jun 4, 2010 1:24:42 PM
* @Version V 1.0
*/
public interface IArticleService {
public List<Article> getArticles(String query);
public boolean createIndex();
}
package com.jushi.lucene.business;
import java.util.List;
import com.jushi.lucene.entities.Article;
/**
* @Author jushi
* @CreateDate Jun 4, 2010 1:24:42 PM
* @Version V 1.0
*/
public interface IArticleService {
public List<Article> getArticles(String query);
public boolean createIndex();
}
3. 接口的实现 ArticleServiceImpl.java 主要的业务在这里实现:创建索引,搜索数据处理。
Java代码
package com.jushi.lucene.business;
import java.io.File;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.queryParser.MultiFieldQueryParser;
import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.Filter;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocs;
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 org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import com.jushi.lucene.dao.IArticleDAO;
import com.jushi.lucene.entities.Article;
/**
* @Author jushi
* @CreateDate Jun 4, 2010 1:25:00 PM
* @Version V 1.0
*/
public class ArticleServiceImpl implements IArticleService {
private IArticleDAO articleDAO;
private final String INDEXPATH = "g:\\index";
private Analyzer analyzer = new StandardAnalyzer();
public List<Article> getArticles(String query) {
try{
List<Article> qlist = new ArrayList<Article>();
String fieldName = "title";
IndexSearcher indexSearcher = new IndexSearcher(INDEXPATH);
//QueryParser parser = new QueryParser(fieldName, analyzer); //单 key 搜索
//Query queryOBJ = parser.parse(query);
System.out.println(">>> 2.开始读取索引... ... 通过关键字:【 "+ query +" 】");
long begin = new Date().getTime();
//下面的是进行title,content 两个范围内进行收索.
BooleanClause.Occur[] clauses = { BooleanClause.Occur.SHOULD,BooleanClause.Occur.SHOULD };
Query queryOBJ = MultiFieldQueryParser.parse(query, new String[]{"title","content"}, clauses, new StandardAnalyzer());//parser.parse(query);
Filter filter = null;
//################# 搜索相似度最高的记录 ###################
TopDocs topDocs = indexSearcher.search(queryOBJ, filter, 1000);
//TopDocs topDocs = indexSearcher.search(queryOBJ , 10000);
System.out.println("*** 共匹配:" + topDocs.totalHits + "个 ***");
Article article = null;
//输出结果
for (ScoreDoc scoreDoc : topDocs.scoreDocs){
Document targetDoc = indexSearcher.doc(scoreDoc.doc);
article = new Article();
//设置高亮显示格式
SimpleHTMLFormatter simpleHTMLFormatter = new SimpleHTMLFormatter("<font color='red'><strong>", "</strong></font>");
/* 语法高亮显示设置 */
Highlighter highlighter = new Highlighter(simpleHTMLFormatter,new QueryScorer(queryOBJ));
highlighter.setTextFragmenter(new SimpleFragmenter(100));
// 设置高亮 设置 title,content 字段
String title = targetDoc.get("title");
String content = targetDoc.get("content");
TokenStream titleTokenStream = analyzer.tokenStream(fieldName,new StringReader(title));
TokenStream contentTokenStream = analyzer.tokenStream("content",new StringReader(content));
String highLightTitle = highlighter.getBestFragment(titleTokenStream, title);
String highLightContent = highlighter.getBestFragment(contentTokenStream, content);
if(highLightTitle == null)
highLightTitle = title;
if(highLightContent == null)
highLightContent = content;
article.setTitle(highLightTitle);
article.setContent(highLightContent);
article.setTag(targetDoc.get("tag"));
article.setTotalHits(topDocs.totalHits);
qlist.add(article);
}
long end = new Date().getTime();
System.out.println(">>> 3.搜索完毕... ... 共花费:" + (end - begin) +"毫秒...");
indexSearcher.close();
return qlist;
}catch(Exception e){
e.printStackTrace();
return null;
}
}
public boolean createIndex()
{
//检查索引是否存在
if(this.isIndexExisted())
return this.isIndexExisted();
List<Article> list = articleDAO.getArticles();
try
{
Directory directory = FSDirectory.getDirectory(INDEXPATH);
IndexWriter indexWriter = new IndexWriter(directory, analyzer ,true, IndexWriter.MaxFieldLength.LIMITED);
long begin = new Date().getTime();
for(Article art: list)
{
Document doc = new Document();
String title = art.getTitle() == null ? "" : art.getTitle().trim();
String content = art.getContent() == null ? "" : art.getContent();
String tag = art.getTag() == null ? "" : art.getTag();
doc.add(new Field("title", title, Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.YES));
doc.add(new Field("content", content, Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.YES));
doc.add(new Field("tag", tag, Field.Store.COMPRESS,Field.Index.NO));
indexWriter.addDocument(doc);
}
long end = new Date().getTime();
System.out.println(">>> 1.存入索引完毕.. 共花费:" + (end - begin) +"毫秒...");
indexWriter.optimize();
indexWriter.close();
return true;
}catch(Exception e){
e.printStackTrace();
return false;
}
}
/**
* check Index is Existed
* @return true or false
*/
private boolean isIndexExisted()
{
try
{
File dir = new File(INDEXPATH);
if(dir.listFiles().length>0)
return true;
else
return false;
}catch(Exception e){
e.printStackTrace();
return false;
}
}
public void setArticleDAO(IArticleDAO articleDAO) {
this.articleDAO = articleDAO;
}
}
package com.jushi.lucene.business;
import java.io.File;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.queryParser.MultiFieldQueryParser;
import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.Filter;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocs;
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 org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import com.jushi.lucene.dao.IArticleDAO;
import com.jushi.lucene.entities.Article;
/**
* @Author jushi
* @CreateDate Jun 4, 2010 1:25:00 PM
* @Version V 1.0
*/
public class ArticleServiceImpl implements IArticleService {
private IArticleDAO articleDAO;
private final String INDEXPATH = "g:\\index";
private Analyzer analyzer = new StandardAnalyzer();
public List<Article> getArticles(String query) {
try{
List<Article> qlist = new ArrayList<Article>();
String fieldName = "title";
IndexSearcher indexSearcher = new IndexSearcher(INDEXPATH);
//QueryParser parser = new QueryParser(fieldName, analyzer); //单 key 搜索
//Query queryOBJ = parser.parse(query);
System.out.println(">>> 2.开始读取索引... ... 通过关键字:【 "+ query +" 】");
long begin = new Date().getTime();
//下面的是进行title,content 两个范围内进行收索.
BooleanClause.Occur[] clauses = { BooleanClause.Occur.SHOULD,BooleanClause.Occur.SHOULD };
Query queryOBJ = MultiFieldQueryParser.parse(query, new String[]{"title","content"}, clauses, new StandardAnalyzer());//parser.parse(query);
Filter filter = null;
//################# 搜索相似度最高的记录 ###################
TopDocs topDocs = indexSearcher.search(queryOBJ, filter, 1000);
//TopDocs topDocs = indexSearcher.search(queryOBJ , 10000);
System.out.println("*** 共匹配:" + topDocs.totalHits + "个 ***");
Article article = null;
//输出结果
for (ScoreDoc scoreDoc : topDocs.scoreDocs){
Document targetDoc = indexSearcher.doc(scoreDoc.doc);
article = new Article();
//设置高亮显示格式
SimpleHTMLFormatter simpleHTMLFormatter = new SimpleHTMLFormatter("<font color='red'><strong>", "</strong></font>");
/* 语法高亮显示设置 */
Highlighter highlighter = new Highlighter(simpleHTMLFormatter,new QueryScorer(queryOBJ));
highlighter.setTextFragmenter(new SimpleFragmenter(100));
// 设置高亮 设置 title,content 字段
String title = targetDoc.get("title");
String content = targetDoc.get("content");
TokenStream titleTokenStream = analyzer.tokenStream(fieldName,new StringReader(title));
TokenStream contentTokenStream = analyzer.tokenStream("content",new StringReader(content));
String highLightTitle = highlighter.getBestFragment(titleTokenStream, title);
String highLightContent = highlighter.getBestFragment(contentTokenStream, content);
if(highLightTitle == null)
highLightTitle = title;
if(highLightContent == null)
highLightContent = content;
article.setTitle(highLightTitle);
article.setContent(highLightContent);
article.setTag(targetDoc.get("tag"));
article.setTotalHits(topDocs.totalHits);
qlist.add(article);
}
long end = new Date().getTime();
System.out.println(">>> 3.搜索完毕... ... 共花费:" + (end - begin) +"毫秒...");
indexSearcher.close();
return qlist;
}catch(Exception e){
e.printStackTrace();
return null;
}
}
public boolean createIndex()
{
//检查索引是否存在
if(this.isIndexExisted())
return this.isIndexExisted();
List<Article> list = articleDAO.getArticles();
try
{
Directory directory = FSDirectory.getDirectory(INDEXPATH);
IndexWriter indexWriter = new IndexWriter(directory, analyzer ,true, IndexWriter.MaxFieldLength.LIMITED);
long begin = new Date().getTime();
for(Article art: list)
{
Document doc = new Document();
String title = art.getTitle() == null ? "" : art.getTitle().trim();
String content = art.getContent() == null ? "" : art.getContent();
String tag = art.getTag() == null ? "" : art.getTag();
doc.add(new Field("title", title, Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.YES));
doc.add(new Field("content", content, Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.YES));
doc.add(new Field("tag", tag, Field.Store.COMPRESS,Field.Index.NO));
indexWriter.addDocument(doc);
}
long end = new Date().getTime();
System.out.println(">>> 1.存入索引完毕.. 共花费:" + (end - begin) +"毫秒...");
indexWriter.optimize();
indexWriter.close();
return true;
}catch(Exception e){
e.printStackTrace();
return false;
}
}
/**
* check Index is Existed
* @return true or false
*/
private boolean isIndexExisted()
{
try
{
File dir = new File(INDEXPATH);
if(dir.listFiles().length>0)
return true;
else
return false;
}catch(Exception e){
e.printStackTrace();
return false;
}
}
public void setArticleDAO(IArticleDAO articleDAO) {
this.articleDAO = articleDAO;
}
}
4. DAO 接口及 DAO实现
Java代码
public interface IArticleDAO {
public List<Article> getArticles();
}
public interface IArticleDAO {
public List<Article> getArticles();
}
Java代码
public class ArticleDAOImpl extends JdbcDaoSupport implements IArticleDAO{
public List<Article> getArticles() {
String sql = "SELECT article_title, article_tag, article_content FROM t_article";
return (List<Article>)this.getJdbcTemplate().query(sql, new ArticleRowMapper());
}
}
public class ArticleDAOImpl extends JdbcDaoSupport implements IArticleDAO{
public List<Article> getArticles() {
String sql = "SELECT article_title, article_tag, article_content FROM t_article";
return (List<Article>)this.getJdbcTemplate().query(sql, new ArticleRowMapper());
}
}
5. 上面DAO需要的 ArticleRowMapper: 这里做了下小改动
Java代码
package com.jushi.lucene.rowmapper;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import org.springframework.jdbc.core.RowMapper;
import com.jushi.lucene.entities.Article;
/**
* @Author jushi
* @CreateDate Jun 4, 2010 1:31:54 PM
* @Version V 1.0
*/
public class ArticleRowMapper implements RowMapper {
public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
Article article = new Article();
ResultSetMetaData meta = rs.getMetaData();
int colNum = meta.getColumnCount();
for (int i = 1; i <= colNum; i++) {
String colName = meta.getColumnName(i).toLowerCase();
if ("article_title".equals(colName)) {
article.setTitle(rs.getString(i));
} else if ("article_content".equals(colName)) {
article.setContent(rs.getString(i));
} else if ("article_tag".equals(colName)) {
article.setTag(rs.getString(i));
//...
}
}
return article;
}
}
package com.jushi.lucene.rowmapper;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import org.springframework.jdbc.core.RowMapper;
import com.jushi.lucene.entities.Article;
/**
* @Author jushi
* @CreateDate Jun 4, 2010 1:31:54 PM
* @Version V 1.0
*/
public class ArticleRowMapper implements RowMapper {
public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
Article article = new Article();
ResultSetMetaData meta = rs.getMetaData();
int colNum = meta.getColumnCount();
for (int i = 1; i <= colNum; i++) {
String colName = meta.getColumnName(i).toLowerCase();
if ("article_title".equals(colName)) {
article.setTitle(rs.getString(i));
} else if ("article_content".equals(colName)) {
article.setContent(rs.getString(i));
} else if ("article_tag".equals(colName)) {
article.setTag(rs.getString(i));
//...
}
}
return article;
}
}
6. Article 实体 添加了两个属性: TotalHits, TotalTime
Java代码
package com.jushi.lucene.entities;
/**
* @Author jushi
* @CreateDate Jun 4, 2010 1:18:48 PM
* @Version V 1.0
*/
public class Article {
private String title;
private String content;
private String tag;
private int TotalHits; //命中率
private int TotalTime; //花费时间
public int getTotalTime() {
return TotalTime;
}
public void setTotalTime(int totalTime) {
TotalTime = totalTime;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getTag() {
return tag;
}
public void setTag(String tag) {
this.tag = tag;
}
public int getTotalHits() {
return TotalHits;
}
public void setTotalHits(int totalHits) {
TotalHits = totalHits;
}
}
package com.jushi.lucene.entities;
/**
* @Author jushi
* @CreateDate Jun 4, 2010 1:18:48 PM
* @Version V 1.0
*/
public class Article {
private String title;
private String content;
private String tag;
private int TotalHits; //命中率
private int TotalTime; //花费时间
public int getTotalTime() {
return TotalTime;
}
public void setTotalTime(int totalTime) {
TotalTime = totalTime;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getTag() {
return tag;
}
public void setTag(String tag) {
this.tag = tag;
}
public int getTotalHits() {
return TotalHits;
}
public void setTotalHits(int totalHits) {
TotalHits = totalHits;
}
}
7. Spring 的配置如下:
--- applicationContext-lucene.xml
Java代码
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
<beans>
<bean id="articleDAO" class="com.jushi.lucene.dao.ArticleDAOImpl" scope="singleton" >
<property name="dataSource" ref="articleDataSource"></property>
</bean>
<bean id="articleService" class="com.jushi.lucene.business.ArticleServiceImpl" scope="singleton" >
<property name="articleDAO" ref="articleDAO"></property>
</bean>
</beans>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
<beans>
<bean id="articleDAO" class="com.jushi.lucene.dao.ArticleDAOImpl" scope="singleton" >
<property name="dataSource" ref="articleDataSource"></property>
</bean>
<bean id="articleService" class="com.jushi.lucene.business.ArticleServiceImpl" scope="singleton" >
<property name="articleDAO" ref="articleDAO"></property>
</bean>
</beans>
--- applicationContext-lucene-datasource.xml
Java代码
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
<beans>
<bean id="articleDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver" ></property>
<property name="url" value="jdbc:mysql://localhost/companyweb?useUnicode=true&characterEncoding=utf-8" />
<property name="username" value="root" />
<property name="password" value="jushi" />
<property name="initialSize" value="5" />
<property name="maxActive" value="20" />
<property name="maxIdle" value="20" />
<property name="minIdle" value="5" />
</bean>
</beans>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
<beans>
<bean id="articleDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver" ></property>
<property name="url" value="jdbc:mysql://localhost/companyweb?useUnicode=true&characterEncoding=utf-8" />
<property name="username" value="root" />
<property name="password" value="jushi" />
<property name="initialSize" value="5" />
<property name="maxActive" value="20" />
<property name="maxIdle" value="20" />
<property name="minIdle" value="5" />
</bean>
</beans>
8. action配置 struts-config.xml
Java代码
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.2//EN" "http://struts.apache.org/dtds/struts-config_1_2.dtd">
<struts-config>
<form-beans>
<form-bean name="lazyForm" type="org.apache.struts.validator.LazyValidatorForm"/>
</form-beans>
<action-mappings>
<action path="/index"
type="com.jushi.lucene.businessview.IndexAction"
name="lazyForm" parameter="m" scope="request" validate="false">
<forward name="result" path="/result.jsp"></forward>
</action>
</action-mappings>
</struts-config>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.2//EN" "http://struts.apache.org/dtds/struts-config_1_2.dtd">
<struts-config>
<form-beans>
<form-bean name="lazyForm" type="org.apache.struts.validator.LazyValidatorForm"/>
</form-beans>
<action-mappings>
<action path="/index"
type="com.jushi.lucene.businessview.IndexAction"
name="lazyForm" parameter="m" scope="request" validate="false">
<forward name="result" path="/result.jsp"></forward>
</action>
</action-mappings>
</struts-config>
9. web.xml 文件配置: 监听、加载配置文件
Java代码
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:/springConfig/applicationContext*.xml</param-value>
</context-param>
<!-- Character Encoding filter -->
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>action</servlet-name>
<servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
<init-param>
<param-name>config</param-name>
<param-value>/WEB-INF/struts-config.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.html</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:/springConfig/applicationContext*.xml</param-value>
</context-param>
<!-- Character Encoding filter -->
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>action</servlet-name>
<servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
<init-param>
<param-name>config</param-name>
<param-value>/WEB-INF/struts-config.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.html</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
10. 前端 View 两个jsp index.jsp和 result.jsp
index.jsp
Java代码
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>简单的lucene测试</title>
<script type="text/javascript" src="js/CheckFunction.js"></script>
<script type="text/javascript">
function _search()
{
var form = document.form1;
if(Trim(form.title.value) == '')
{
alert("输入一个关键字吧!");
return false;
}
form.action = 'index.html?m=index';
form.submit();
}
</script>
</head>
<body>
<center><h1>测试Lucene</h1>
<hr/>
<form name="form1" action="index.html" method="post">
请输入文章的标题关键字:<input type="text" maxlength="20" name="title" size="40"/>
<button onclick="javascript:_search();return false;" style="border: thin;border-color: blue" name="search"> GO </button>
</form>
</center>
</body>
</html>
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>简单的lucene测试</title>
<script type="text/javascript" src="js/CheckFunction.js"></script>
<script type="text/javascript">
function _search()
{
var form = document.form1;
if(Trim(form.title.value) == '')
{
alert("输入一个关键字吧!");
return false;
}
form.action = 'index.html?m=index';
form.submit();
}
</script>
</head>
<body>
<center><h1>测试Lucene</h1>
<hr/>
<form name="form1" action="index.html" method="post">
请输入文章的标题关键字:<input type="text" maxlength="20" name="title" size="40"/>
<button onclick="javascript:_search();return false;" style="border: thin;border-color: blue" name="search"> GO </button>
</form>
</center>
</body>
</html>
result.jsp
Java代码
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ page import="com.jushi.lucene.entities.*"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<%
List<Article> list = (List<Article>) request.getAttribute("articlelist");
String TotalTime = "0.000";
int TotalHits = 0;
if(request.getAttribute("totalTime")!=null)
TotalTime = request.getAttribute("totalTime").toString();
if(list.size()>0 && list!=null)
TotalHits = list.get(0).getTotalHits();
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>搜索的结果如下:</title>
<style type="text/css">
.Fee {
width: 650px;
height:28px;
float: right;
padding:1px;
overflow:hidden;
border-bottom:1px solid #bde2ff;
line-height:28px;
font-family: '宋体';
font-size: 15px;
font-weight: bold;
}
.Fee span {
color: red;
font-size:14px;
}
</style>
</head>
<body>
<div class="Fee">共搜到 <span><%=TotalHits %></span> 条结果. 共花费:<span><%=TotalTime %> </span>秒.</div><br/><br/>
<table width="80%" height="70%" border="1" cellpadding="0" cellspacing="0" align="center">
<tr height="20" bgcolor="#CCCCCC">
<td align="center" width="20%">标题</td>
<td align="center" width="60%">文章内容</td>
<td align="center" width="20%">所属标签</td>
</tr>
<%
if(list.size()>0){
for(Article art : list){
String title = art.getTitle();
String content = art.getContent();
String tag = art.getTag();
%>
<tr>
<td><%=title %></td>
<td><%=content %></td>
<td><%=tag %></td>
</tr>
<%}}else{ %>
<tr>
<td colspan="3" align="center"><h3>对不起...没有搜到相关信息..请尝试其他关键字!</h3></td>
</tr>
<%} %>
</table>
<br/>
<center><a href="<%=basePath %>./">返回上一级</a></center>
</body>
</html>
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ page import="com.jushi.lucene.entities.*"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<%
List<Article> list = (List<Article>) request.getAttribute("articlelist");
String TotalTime = "0.000";
int TotalHits = 0;
if(request.getAttribute("totalTime")!=null)
TotalTime = request.getAttribute("totalTime").toString();
if(list.size()>0 && list!=null)
TotalHits = list.get(0).getTotalHits();
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>搜索的结果如下:</title>
<style type="text/css">
.Fee {
width: 650px;
height:28px;
float: right;
padding:1px;
overflow:hidden;
border-bottom:1px solid #bde2ff;
line-height:28px;
font-family: '宋体';
font-size: 15px;
font-weight: bold;
}
.Fee span {
color: red;
font-size:14px;
}
</style>
</head>
<body>
<div class="Fee">共搜到 <span><%=TotalHits %></span> 条结果. 共花费:<span><%=TotalTime %> </span>秒.</div><br/><br/>
<table width="80%" height="70%" border="1" cellpadding="0" cellspacing="0" align="center">
<tr height="20" bgcolor="#CCCCCC">
<td align="center" width="20%">标题</td>
<td align="center" width="60%">文章内容</td>
<td align="center" width="20%">所属标签</td>
</tr>
<%
if(list.size()>0){
for(Article art : list){
String title = art.getTitle();
String content = art.getContent();
String tag = art.getTag();
%>
<tr>
<td><%=title %></td>
<td><%=content %></td>
<td><%=tag %></td>
</tr>
<%}}else{ %>
<tr>
<td colspan="3" align="center"><h3>对不起...没有搜到相关信息..请尝试其他关键字!</h3></td>
</tr>
<%} %>
</table>
<br/>
<center><a href="<%=basePath %>./">返回上一级</a></center>
</body>
</html>
12. action:IndexAction.java
Java代码
package com.jushi.lucene.businessview;
import java.text.DecimalFormat;
import java.util.Date;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.actions.DispatchAction;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import com.jushi.lucene.business.IArticleService;
import com.jushi.lucene.entities.Article;
/**
* @Author fenglong
* @CreateDate Jun 4, 2010 1:50:02 PM
* @Version V 1.0
* @CopyRight 2010 jushi
*/
public class IndexAction extends DispatchAction {
public ActionForward index(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(this.getServlet().getServletContext());
IArticleService articleService = (IArticleService) wac.getBean("articleService");
String q = request.getParameter("title");
DecimalFormat df = new DecimalFormat("#0.000");
if(articleService.createIndex()){
long begin = new Date().getTime();
List<Article> list = articleService.getArticles(q);
long end = new Date().getTime();
double time = (double) (end - begin) / 1000;
String timeStr = df.format(time);
request.setAttribute("totalTime", timeStr);
request.setAttribute("articlelist", list);
}
return mapping.findForward("result");
}
}
package com.jushi.lucene.businessview;
import java.text.DecimalFormat;
import java.util.Date;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.actions.DispatchAction;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import com.jushi.lucene.business.IArticleService;
import com.jushi.lucene.entities.Article;
/**
* @Author fenglong
* @CreateDate Jun 4, 2010 1:50:02 PM
* @Version V 1.0
* @CopyRight 2010 jushi
*/
public class IndexAction extends DispatchAction {
public ActionForward index(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(this.getServlet().getServletContext());
IArticleService articleService = (IArticleService) wac.getBean("articleService");
String q = request.getParameter("title");
DecimalFormat df = new DecimalFormat("#0.000");
if(articleService.createIndex()){
long begin = new Date().getTime();
List<Article> list = articleService.getArticles(q);
long end = new Date().getTime();
double time = (double) (end - begin) / 1000;
String timeStr = df.format(time);
request.setAttribute("totalTime", timeStr);
request.setAttribute("articlelist", list);
}
return mapping.findForward("result");
}
}
好了,所有的配置已经完成了。大概就是个Lucene的简单实现。只是稍微的和Spring结合了一下。功能就是搜索数据,高亮显示关键字。页面不好看,逻辑教简单。
欢迎拍砖。
发表评论
-
如何优化Lucene
2009-08-18 18:27 12141·关闭复合文件格式 调用setUseComp ... -
lucene实现多词/短语搜索
2009-07-14 10:57 2164不知道这个方法是否可行,我简单做了个测试。貌似还行。把具体的代 ... -
lucene索引中单词或者是多词高亮的处理
2009-07-09 09:43 1723高亮的处理lucene为我们提供了Highlighter,利用 ... -
一个有关lucene的困惑!(lucene的过滤问题)
2009-07-07 13:17 1112我现在有这么一个问题: ... -
lucene中paoding的中文分词
2009-07-02 14:11 13981,把paoding-analysis-2.0.4-beta解 ... -
Lucene中文分词组件JE-Analysis1.5.0
2009-07-02 00:15 3872<!-- Title Start--> L ... -
lucene综合使用
2009-07-02 00:09 1327I.Sorting search results 在Luce ... -
lucene的sort的使用
2009-07-02 00:05 2520Lucene的搜索结果默认按相关度排序,这个相关度排序是基于内 ... -
lucene的各个包的说明
2009-06-30 22:15 1363Lucene各个包的说明: org.apache.lucen ... -
lucene中IndexSearch,Query,Hits的总结
2009-06-30 22:08 2610IndexSearch类 查询器 搜索入口,继承自Searc ...
相关推荐
“Lucene与数据库结合示例(加双关键字高亮)”这个标题表明,我们将讨论如何将开源全文搜索引擎Lucene与关系型数据库MySQL整合在一起,并且在搜索结果中实现关键词高亮显示,以提升用户体验。这通常涉及到数据的...
总之,将 Lucene 与数据库结合可以提供强大的搜索能力,尤其是在需要对结构化数据进行全文检索的情况下。理解如何正确地连接、查询和索引数据库记录是实现这一目标的关键。通过深入研究 `lucenetestsql` 示例代码,...
然而,Lucene可以与数据库结合使用,以实现高效的全文搜索和索引。在这个主题中,我们将深入探讨如何利用Lucene对数据库中的数据进行索引和查询。 首先,我们需要理解Lucene的工作原理。Lucene通过分析文本,将其...
《lucene检索数据库.doc》则聚焦于Lucene如何与数据库结合使用。文档中探讨了如何将数据库中的数据导入Lucene索引,以及如何在查询时结合数据库进行高效的数据检索。这对于那些需要处理大量结构化数据的应用来说,是...
需要注意的是,Lucene虽然强大,但其主要负责文本搜索,对于数据库中非文本信息的处理,可能需要结合其他手段。此外,为了确保最佳性能,需要定期维护和优化索引,以及选择适合应用场景的分析器。
在本文中,我们将探讨如何使用Lucene建立数据库索引,并分享一些在实践过程中的经验和教训。Lucene是一个高性能、全文本搜索库,广泛用于构建搜索引擎。在创建索引时,需要注意以下关键点: 1. **资料的准确性**:...
在这个项目中,我们将探讨如何利用Lucene 2.4.0版本与Access数据库结合,实现对数据库内容的全文检索。 首先,我们需要理解Lucene的基本工作原理。Lucene的核心概念包括文档(Document)、字段(Field)和索引...
本Demo源码展示了如何将Lucene.NET与SQL数据库结合,以实现对数据库存储的文本数据进行全文检索。通常,我们会在数据库中存储大量结构化数据,而使用Lucene.NET可以对这些非结构化的文本信息进行高效的检索。 **...
在结合数据库操作时,需要注意合理地将数据库字段映射到Lucene的索引结构中,以及正确选择和使用分析器进行文本处理。同时,对于Web应用,需要考虑如何将搜索结果与用户界面相结合,提供良好的用户体验。
下面将详细阐述Lucene的基本概念、如何在Java环境中使用Lucene进行全文检索,以及结合MySQL数据库的具体实现案例。 ### Lucene简介 Lucene是一个高性能、全功能的文本搜索引擎库,由Doug Cutting创建并开源。它为...
《Lucene检索数据库支持中文检索...开发者可以通过配置文件管理数据库连接,结合工具类处理索引和搜索过程,实现定制化的搜索功能。在实际项目中,可以根据需求选择合适的Analyzer来优化中文文本的处理,提升搜索效果。
本文主要介绍了一个将Lucene搜索引擎与数据库(MySQL)结合的示例,用于实现文本检索功能。Lucene是Apache软件基金会的开源全文检索库,它提供了强大的文本分析和索引构建能力。在本示例中,作者使用Spring和Struts1...
本文探讨了一种基于Lucene检索引擎的全文数据库的实现方案,通过将全文检索技术与文件系统相结合,有效地解决了非结构化文本数据的管理和检索问题。这种方法不仅提高了检索效率,还降低了系统的复杂度,对于需要处理...
6. **Lucene与数据库结合** - **数据库集成**: 通过JDBC或其他方式将数据库中的数据导入Lucene索引,实现高效全文检索。 - **联合查询(Hybrid Search)**: 结合SQL查询与Lucene的全文搜索,提供更强大的搜索能力...
《使用Lucene实现数据库检索》 Lucene是一个高性能、全文本搜索库,广泛应用于各种应用场景,包括搜索引擎、信息检索系统等。它提供了高效的索引和搜索功能,使得开发者能够快速地从海量数据中找到目标信息。本文将...
本实例将探讨如何结合Lucene和SQL Server数据库来实现高效的索引和搜索功能。 Lucene是一个由Apache软件基金会开发的全文检索库,它提供了一个高级的、可扩展的、基于Java的搜索程序库。Lucene的核心功能包括文档的...
本文将深入探讨Lucene引擎与SQLite数据库在分词查询中的应用,以及如何通过它们来统计单词频率、识别重点单词和句子。 首先,Lucene是一个高性能、全文检索库,由Apache软件基金会开发。它提供了一个高效的、可扩展...