有点样子了,当然还有很多要优化的地方,用lucene做一个站内搜索,我用的是lucene3.0.1.
首先看看数据库,我用的新闻模拟的:新闻表
CREATE TABLE `t_newsitem` (
`Id` int(11) NOT NULL auto_increment,
`editor` varchar(255) default NULL,
`newsContent` longtext,
`newsTitle` varchar(255) default NULL,
`publishTime` datetime default NULL,
`resoure` varchar(255) default NULL,
`t_newsType_id` int(11) default NULL,
`resource` varchar(255) default NULL,
PRIMARY KEY (`Id`),
KEY `FK9CB4BF1923597B2` (`t_newsType_id`),
KEY `FK9CB4BF19FFB60BE` (`t_newsType_id`),
CONSTRAINT `fk` FOREIGN KEY (`t_newsType_id`) REFERENCES `t_newstype` (`Id`),
CONSTRAINT `FK9CB4BF1923597B2` FOREIGN KEY (`t_newsType_id`) REFERENCES `t_newstype` (`Id`),
CONSTRAINT `FK9CB4BF19FFB60BE` FOREIGN KEY (`t_newsType_id`) REFERENCES `t_newstype` (`Id`)
) ENGINE=InnoDB DEFAULT CHARSET=gbk;
新闻类型表(也没啥用):
CREATE TABLE `t_newstype` (
`Id` int(11) NOT NULL auto_increment,
`newsTypeName` varchar(255) default NULL,
PRIMARY KEY (`Id`)
) ENGINE=InnoDB DEFAULT CHARSET=gbk;
系统是ssh么,站内搜索是基于它们的。
要使用lucene,至少要添加lucene-core-3.0.1.jar(核心),lucene-highlighter-3.0.1.jar(高亮显示),lucene-analyzers-3.0.1.jar(分词器)。因为它自带的分词器对中文支持不好,我使用了IKAnalyzer分词器,IKAnalyzer3.2.3Stable.jar。
做好上面的准备工作,下面就是编写下面的两个类了:
package luence;
import java.io.File;
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.List;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.store.LockObtainFailedException;
import org.apache.lucene.store.SimpleFSDirectory;
import org.htmlparser.Parser;
import org.wltea.analyzer.lucene.IKAnalyzer;
import service.NewsService;
import entity.TNewsitem;
/**
* 创建索引库
*
* @author tqc
*
*/
public class IndexCreate {
String path = "C:/index";// 索引所在文件夹
String path2 = "C:/index2";// tag索引所在文件夹
Analyzer analyzer=new IKAnalyzer();
NewsService service = null;
public NewsService getService() {
return service;
}
public void setService(NewsService service) {
this.service = service;
}
/**
* 创建全文新闻索引
*/
@SuppressWarnings("unchecked")
public void createIndexForNews() throws Exception {
IndexWriter indexWriter = new IndexWriter(new SimpleFSDirectory(new File(path)), analyzer, true,IndexWriter.MaxFieldLength.LIMITED);
List<TNewsitem> list = service.getNews();
DateFormat format = new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒");
// 对所有的新闻实体进行索引创建
for (TNewsitem newsItem : list) {
Document doc = new Document();
String newsTitle = newsItem.getNewsTitle();
String newsContent = newsItem.getNewsContent();
String publishDate = format.format(newsItem.getPublishTime());
String id = newsItem.getId() + "";
doc.add(new Field("title", newsTitle, Field.Store.YES,
Field.Index.ANALYZED));
Parser parser = new Parser();
parser.setInputHTML(newsContent);
String strings = parser.parse(null).elementAt(0)
.toPlainTextString().trim();
doc.add(new Field("content", strings, Field.Store.YES,
Field.Index.ANALYZED));
doc.add(new Field("date", publishDate, Field.Store.YES,
Field.Index.NOT_ANALYZED));
doc.add(new Field("id", id, Field.Store.YES, Field.Index.NO));
indexWriter.addDocument(doc);
}
// 优化索引
indexWriter.optimize();
indexWriter.close();
}
/**
* 为tag创建索引
* @throws IOException
* @throws LockObtainFailedException
* @throws CorruptIndexException
*/
@SuppressWarnings("unchecked")
public void createIndexForTag() throws CorruptIndexException, LockObtainFailedException, IOException{
IndexWriter indexWriter = new IndexWriter(new SimpleFSDirectory(new File(path2)), analyzer, true,IndexWriter.MaxFieldLength.LIMITED);
List<TNewsitem> list = service.getNews();
for (TNewsitem newsItem : list) {
Document doc = new Document();
String tags = newsItem.getNewsTitle();
doc.add(new Field("tags", tags, Field.Store.YES,
Field.Index.ANALYZED));
indexWriter.addDocument(doc);
}
// 优化索引
indexWriter.optimize();
indexWriter.close();
}
上面这个类主要是用来创建索引。
package luence;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.queryParser.MultiFieldQueryParser;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.queryParser.QueryParser;
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.Formatter;
import org.apache.lucene.search.highlight.Fragmenter;
import org.apache.lucene.search.highlight.Highlighter;
import org.apache.lucene.search.highlight.QueryScorer;
import org.apache.lucene.search.highlight.Scorer;
import org.apache.lucene.search.highlight.SimpleFragmenter;
import org.apache.lucene.search.highlight.SimpleHTMLFormatter;
import org.apache.lucene.store.SimpleFSDirectory;
import org.apache.lucene.util.Version;
import org.wltea.analyzer.lucene.IKAnalyzer;
import entity.SearchResultBean;
/**
* 查询索引库
*
* @author tqc
*
*/
public class IndexSearch {
String path = "C:/index";// 索引所在文件夹
String path2 = "C:/index2";// tag索引所在文件夹
Analyzer analyzer = new IKAnalyzer();// 中文分词器
/**
* 条件查询 显示高亮效果
*
* @param searchParam
* @return
* @throws Exception
*/
public List<SearchResultBean> getSearchResult(String searchParam)
throws Exception {
IndexReader reader = IndexReader.open(new SimpleFSDirectory(new File(
path)));
String[] fileds = { "title", "content" };// 在哪些字段中查询
QueryParser parser = new MultiFieldQueryParser(Version.LUCENE_30,
fileds, analyzer);
IndexSearcher searcher = new IndexSearcher(reader);
Query query = parser.parse(searchParam);
TopDocs docs = searcher.search(query, 10000);
System.out.println("--->匹配总个数:" + docs.totalHits);
List<SearchResultBean> list = new ArrayList<SearchResultBean>();
Formatter formatter = new SimpleHTMLFormatter("<b><font color='red'>",
"</font></b>");
Scorer scorer = new QueryScorer(query);
Highlighter highlighter = new Highlighter(formatter, scorer);
Fragmenter fragmenter = new SimpleFragmenter(50);
highlighter.setTextFragmenter(fragmenter);
for (ScoreDoc scoredoc : docs.scoreDocs) {
int docSn = scoredoc.doc;
Document doc = searcher.doc(docSn);
SearchResultBean srb = new SearchResultBean();
String id = doc.get("id");
String date = doc.get("date");
String c = highlighter.getBestFragment(analyzer, "content", doc.get("content"));
if (c == null) {
String content = doc.get("content");
int endIndex = Math.min(100, content.length());
c=content.substring(0,endIndex);
}
doc.getField("content").setValue(c);
String t = highlighter.getBestFragment(analyzer, "title", doc.get("title"));
if (t == null) {
String title = doc.get("title");
int endIndex = Math.min(20, title.length());
t=title.substring(0,endIndex);
}
doc.getField("title").setValue(t);
String content = doc.get("content");
String title = doc.get("title");
srb.setContent(content);
srb.setTitle(title);
srb.setDate(date);
srb.setId(id);
list.add(srb);
}
return list;
}
/**
* 关键词查询tag索引
*
* @throws IOException
* @throws CorruptIndexException
* @throws ParseException
*/
@SuppressWarnings("unchecked")
public List TermQuery(String key) throws CorruptIndexException, IOException, ParseException {
IndexReader reader = IndexReader.open(new SimpleFSDirectory(new File(
path2)));
IndexSearcher searcher = new IndexSearcher(reader);
QueryParser parser = new QueryParser(Version.LUCENE_30,"tags",analyzer);
Query query = parser.parse(key);
System.out.println(key);
TopDocs docs = searcher.search(query, 10000);
System.out.println("--->匹配总个数:" + docs.totalHits);
List<SearchResultBean> list = new ArrayList();
for (ScoreDoc scoredoc : docs.scoreDocs) {
int docSn = scoredoc.doc;
Document doc = searcher.doc(docSn);
SearchResultBean srb = new SearchResultBean();
String tag = doc.get("tags");
srb.setTitle(tag);
list.add(srb);
}
return list;
}
}
}
这个类用于查询索引库。
接下来在action中使用了,
/**
* 创建索引
*
* @return
* @throws Exception
*/
public String c() throws Exception {
indexCreate.createIndexForNews();// 创建索引
indexCreate.createIndexForTag();// tag创建索引
System.out.println("-->索引创建成功!");
return "index";
}
/**
* 搜
*
* @return
* @throws Exception
*/
@SuppressWarnings("unchecked")
public String s() throws Exception {
String searchParam = ServletActionContext.getRequest().getParameter(
"key");
if (searchParam == "") {
return "index";
}
List list = indexSearch.getSearchResult(searchParam);
ServletActionContext.getRequest().setAttribute("res", list);
return "index";
}
因为客户要像百度那样的,在文本框输入后可以自动补全提示的,所以下一步我是去客户端看看了
<script type="text/javascript" src="js/jquery.js"></script>
<script type='text/javascript' src='js/jquery.autocomplete.js'></script>
<link type="text/css" rel="stylesheet" href="css/jquery.autocomplete.css" />
我使用的是jquery的autocomplete插件。
<script type="text/javascript">
$(function() {
$("#product").autocomplete("s!s", {
minChars: 1, //最小提示字符
width: 360, //提示框的长度
autoFill: false, //不自动填充
multiple: false, //不允许多个自动填充值出现
dataType: "json", //数据类型
parse: function(data) { //解析数据
return $.map(data, function(row) {
return {
data: row,
value: row.value,
result: row.value //显示在文本框里面的格式
}
});
},
formatItem: function(row, i, max) { //格式化显示的内容
return row.value+" 第"+i+"条记录,共"+max+"条";
},
formatMatch: function(row, i, max) {
return row.name + " " + row.value;
},
formatResult: function(row) {
return row.value;
}
});
});
</script>
因为是ajax的,给看看后台是如何处理的,
/**
* 完成自动补全
*
* @return
* @throws Exception
*/
@SuppressWarnings("unchecked")
public String s() throws Exception {
ServletActionContext.getResponse().setContentType(
"text/json;charset=UTF-8");
HttpServletRequest request = ServletActionContext.getRequest();
String key = request.getParameter("q");
key = new String(key.getBytes("ISO-8859-1"), "utf-8");
List<SearchResultBean> list = indexSearch.TermQuery(key);
StringBuffer sg = new StringBuffer();
sg.append("[");
for (int i = 0; i < list.size(); i++) {
SearchResultBean s = list.get(i);
if (i == list.size() - 1) {
sg.append("{name:'eee',value:'" + s.getTitle() + "'}");
} else {
sg.append("{name:'eee',value:'" + s.getTitle() + "'},");
}
}
sg.append("]");
ServletActionContext.getResponse().getWriter().print(sg.toString());
return null;
}
返回的json格式。到目前基本上就搞定了!
分享到:
相关推荐
通过搜索引擎从互联网上获取有用信息已经成为人们生活的重要组成部分,Lucene是构建搜索引擎的其中一种方式。搜索引擎系统是在.Net平台上用C#开发的,数据库是MSSQL Server。主要完成的功能有:用爬虫抓取网页;获取...
标题"AJAX + Lucene 构建搜索引擎"指出,这是一个关于如何使用AJAX(异步JavaScript和XML)技术和Apache Lucene(一个高性能全文搜索引擎库)来构建自定义搜索引擎的项目或教程。这个技术组合允许开发者创建交互性强...
在这个项目中,我们探索了如何结合Apache Lucene和WebMagic这两个强大的工具来构建一个专门针对交通领域的垂直搜索引擎。Apache Lucene是一个开源全文搜索引擎库,它提供了高级文本分析和索引功能,而WebMagic则是一...
而Lucene则是一个高性能、全文检索库,为构建搜索引擎提供了强大的后端支持。 首先,ASP.NET作为基础架构,可以提供稳定且高效的服务器端处理能力。利用其内置的页面生命周期管理、状态管理以及控件模型,开发者...
《ajax+lucene构建搜索引擎》一书的源代码
### 精通Ajax+Lucene构建搜索引擎 #### Ajax与Lucene概述 本文旨在深入探讨如何结合Ajax与Lucene技术构建高效、响应迅速的搜索引擎。首先,我们需要理解Ajax与Lucene各自的技术特点及其应用场景。 **Ajax...
计算机毕业设计_ASP.NET基于Ajax+Lucene构建搜索引擎的设计和实现(源代码+)__毕设源码实例.zip计算机毕业设计_ASP.NET基于Ajax+Lucene构建搜索引擎的设计和实现(源代码+)__毕设源码实例.zip计算机毕业设计_ASP.NET...
《Ajax+Lucene构建搜索引擎》.part1 源代码光盘,189个代码示例
《Ajax+Lucene构建搜索引擎》.part3 源代码光盘,189个代码示例
《Ajax+Lucene构建搜索引擎》.part2 源代码光盘,189个代码示例
Lucene作为一个强大的全文搜索引擎库,为开发者提供了高效的文本搜索能力;Compass作为Lucene的一个高级封装,简化了在应用程序中集成搜索引擎的操作;而Ajax(Asynchronous JavaScript and XML)则通过异步通信提升...
本项目"ASP.NET基于Ajax+Lucene构建搜索引擎的设计和实现_project"旨在提供一种解决方案,利用现代Web技术和开源全文搜索引擎库来创建用户友好的搜索体验。 首先,ASP.NET是Microsoft开发的一个用于构建动态Web应用...
asp代码ASP.NET基于Ajax+Lucene构建搜索引擎的设计和实现(源代码+论文)本资源系百度网盘分享地址
索引是现代搜索引擎的核心,建立索引是把数据源处理成非常方便查询的索引文件的过程。为什么索引这么重要呢,试想你现在要在大量的文档中搜索含有某个关键词的文档,那么如果不建立索引的话你就需要把这些文档顺序的...
ASP.NET基于Ajax+Lucene构建搜索引擎的设计和实现(源代码+论文)
1. 系统架构设计:阐述了如何结合ASP.NET、Ajax和Lucene构建搜索引擎的总体架构,包括前端用户界面、后台服务和数据库的交互方式。 2. 数据处理:详细描述了数据预处理的过程,如文本标准化、分词策略以及如何构建和...
这篇资料——"ASP.NET基于Ajax+Lucene构建搜索引擎的设计和实现(源代码+论文)",提供了一种利用ASP.NET、Ajax和Lucene技术来构建搜索引擎的方法。以下是这个项目的核心知识点: **ASP.NET**:ASP.NET是微软开发的一...