DotLucene的官方网站这样介绍:DotLucene是一个专门为NET设计的功能强大的搜索引擎!他上面也有一个在线demo,搜索 3.5GB的文本数据所花费的时间在0.1秒左右!大家可以点这里测试。我也记得在我的一个网站99 收藏夹(注1)里面有个在线帮助,他是用StreamReader来读文本数据的,其他的是读数据库,我发现不管是读数据库还是一xml的形式读xml文 档,不管你的数据库如何优化,也不管你的机器培植如何之高,读的速度与读文本数据的速度是不可比的,大家也可到http://www.99scj.com测试下。点在线帮助,一闪就出来了。
在上篇文章我们说了怎么建立索引,现在说的是怎么搜索这个索引,最主要的我们是要理解startAt的含义,理解了他什么问 题都解决了。还有这个例子的分页很经典,我发现google和baidu用的都是这个分页方法。主要就两个方法,一个search()方法,主要是显示当 前页的搜索记录
}
#region Web 窗体设计器生成的代码
override protected void OnInit(EventArgs e)
{
//
// CODEGEN: 该调用是 ASP.NET Web 窗体设计器所必需的。
//
InitializeComponent();
base.OnInit(e);
}
/// <summary>
/// 设计器支持所需的方法 - 不要使用代码编辑器修改
/// 此方法的内容。
/// </summary>
private void InitializeComponent()
{
this.Button1.Click += new System.EventHandler(this.Button1_Click);
this.Button2.Click += new System.EventHandler(this.Button2_Click);
this.Load += new System.EventHandler(this.Page_Load);
}
#endregion
protected void IndexBook(Result rs,IndexWriter writer)
{
Document doc = new Document();
doc.Add(Field.Keyword("Title", rs.Title));
doc.Add(Field.Keyword("CopyFrom",rs.CopyFrom));
doc.Add(Field.Keyword("UpdateTime",rs.UpdateTime.ToString()));
doc.Add(Field.Text("Content", rs.Content));
doc.Add(Field.Text("DefaultPicUrl",rs.DefaultPicUrl));
doc.Add(Field.Text("IncludePic",rs.InclucePic.ToString()));
writer.AddDocument(doc);
}
private string ParseHtml(string html)
{
string temp = Regex.Replace(html,"<[^>]*>|<|>","");
return temp.Replace(" "," ");
}
protected void Button1_Click(object sender, System.EventArgs e)
{
for(int t=0;t<1;t++)
{
System.Threading.Thread thread=new Thread(new ThreadStart(InitIndex));
thread.Start();
}
}
private IndexWriter GetWriter(string physicalPath)
{
IndexWriter indexWriter = null;
string segmentFile = System.IO.Path.Combine(physicalPath, "segments");
if ( System.IO.File.Exists(segmentFile) )
indexWriter = new IndexWriter(physicalPath, new Lucene.Net.Analysis.Cn.ChineseAnalyzer(), false);
else
indexWriter = new IndexWriter(physicalPath, new Lucene.Net.Analysis.Cn.ChineseAnalyzer(), true);
return indexWriter;
}
private void InitIndex()
{
int index=0;
int end = 0;
// IndexWriter iw=new IndexWriter(@"D:\Index",ca,true);
IndexWriter iw=GetWriter(@"D:\study\XK_Vote\Index");
iw.mergeFactor = 15;
while(true)
{
DB db=new DB();
System.Data.SqlClient.SqlDataReader sdr=null;
System.Data.SqlClient.SqlParameter [] p={db.MakeInParam("@id",SqlDbType.Int,4,index)};
db.RunProc("GZ_SelectText",p,out sdr);
int count = 0;
while(sdr.Read())
{
Result rs=new Result();
rs.Title=sdr["Title"].ToString();
rs.Content=this.ParseHtml(sdr["Content"].ToString());
rs.CopyFrom=sdr["CopyFrom"].ToString();
if(Convert.ToInt32(sdr["IncludePic"])==1)
{
rs.InclucePic=Convert.ToInt32(sdr["IncludePic"]);
rs.DefaultPicUrl=sdr["DefaultPicUrl"].ToString();
}
else
{
rs.InclucePic=0;
rs.DefaultPicUrl="";
}
rs.UpdateTime=Convert.ToDateTime(sdr["UpdateTime"].ToString());
IndexBook(rs,iw);
index=Convert.ToInt32(sdr["ArticleID"]);
count++;
}
end++;
if(count < 100-1)
break;
if(end > 200)
break;
}
iw.Optimize();
iw.Close();
}
private void Button2_Click(object sender, System.EventArgs e)
{
this.Query=Convert.ToString(Request.Form["Content"]);
// Search();
DataBind();
}
/*protected void Search()
{
DateTime start = DateTime.Now;//搜索的开始时间
Lucene.Net.Search.IndexSearcher search=new Lucene.Net.Search.IndexSearcher(@"D:\LuceneIndex");
string [] fields={"Content","Title"};
Query multiquery = MultiFieldQueryParser.Parse(this.Query,fields,new ChineseAnalyzer());
this.Results.Columns.Add("Title",typeof(string));
this.Results.Columns.Add("Content",typeof(string));
// this.Results.Columns.Add("CopyFrom",typeof(string));
// this.Results.Columns.Add("UpdateTime",typeof(string));
QueryHighlightExtractor highlighter = new QueryHighlightExtractor(multiquery, new ChineseAnalyzer(), "<font color=red>", "</font>");
Lucene.Net.Search.Hits hit =search.Search(multiquery);
//初始化startAt,以便得到要显示的结果集
this.total=hit.Length();
this.startAt = initStartAt();
//得到当前页要显示的记录数量,包括以前所有页的记录数,这样把他与this.startAt结合就能够很好的知道当前页要显示的记录数了
int resultsCount = smallOf(this.total,this.startAt+this.maxResults);
//开始循环得到当前页要显示的记录ex
for (int i = this.total - this.startAt-1; i >= this.total - resultsCount; i--)
{
DataRow dr = this.Results.NewRow();
dr["Title"] = highlighter.GetBestFragments(hit.Doc(i).GetField("Title").StringValue(),1,2,"...");
dr["Content"] = highlighter.GetBestFragments(hit.Doc(i).GetField("Content").StringValue(),80,2,"...");
// dr["CopyFrom"]= hit.Doc(i).GetField("CopyFrom").StringValue();
// dr["UpdateTime"]=hit.Doc(i).GetField("UpdateTime").StringValue();
//把行添加进DataTable
this.Results.Rows.Add(dr);
}
//循环完毕,关闭搜索
search.Close();
//搜索花费多少时间
this.duration = DateTime.Now - start;
Response.Write(this.duration);
//给fromItem赋值,他总是startAt+1
this.fromItem = this.startAt + 1;
//给toItem赋值
this.toItem = smallOf(this.total,this.startAt+this.maxResults);
}*/
/// <summary>
/// 开始分页
/// </summary>
/// <returns></returns>
protected DataTable Paging
{
get
{
//知道了startAt,分页也很容易了,现在根据startAt得到当前是第几页,注意,现在这里的页数也是暂时从0开始的
int pageNumber = (this.startAt + this.maxResults - 1) / this.maxResults;
DataTable dt = new DataTable();
dt.Columns.Add("html");
DataRow dr = dt.NewRow();
//暂时得到当前页的html连接,注意这里当真正显示页数的时候要+1
dr["html"] = pagingNumberHtml(startAt,pageNumber+1,false);
dt.Rows.Add(dr);
//前面显示10页,如果有的话
int previousPagesCount = 10;
//循环把前面页的html连接插到前面去
for (int i = pageNumber - 1; i >= 0 && i >= pageNumber - previousPagesCount; i--)
{
DataRow r = dt.NewRow();
r["html"] = pagingNumberHtml(i*this.maxResults,i+1,true);
dt.Rows.InsertAt(r,0);;
}
//后面也显示10页,如果有的话
int nextPagesCount = 10;
for (int i = pageNumber + 1; i <= this.pageCount && i <= pageNumber + nextPagesCount; i++)
{
DataRow r = dt.NewRow();
r["html"] = pagingNumberHtml(i*this.maxResults,i+1,true);
dt.Rows.Add(r);
}
//添加下一页的超级连接
DataRow lastRow = dt.NewRow();
lastRow["html"] = "<a href='WebForm1.aspx?q=" + HttpUtility.UrlEncode(this.Query) + "&start=" + (pageNumber + 1) * this.maxResults + "'>下一页</a>";
dt.Rows.Add(lastRow);
return dt;
}
}
/// <summary>
/// 得到某一页的html连接字符串
/// </summary>
/// <param name="start">页是从那条记录开始搜索的</param>
/// <param name="number">页数</param>
/// <param name="active">是不是个超级连接</param>
/// <returns></returns>
private string pagingNumberHtml(int start, int number, bool active)
{
if (active)
{
return "<a href='WebForm1.aspx?q="+HttpUtility.UrlEncode(this.Query)+"&start="+start+"'>"+number+"</a>";
}
else
{
return "<span style='font-weight:bold;'>'+number+'</span>'";
}
}
private int smallOf(int first, int second)
{
return first < second ? first : second;//得到两个数之间的较少数
}
private int initStartAt()
{
try
{
int sa = Convert.ToInt32(this.Request.Params["start"]);
if (sa < 0)
return 0;
if (sa >= this.total - 1)
return lastPageStartAt;//如果不足以显示三条,从最后页的第0条开始显示
return sa;
}
catch
{
return 0;//如果输入非法非数字,那么从第0条开始显示
}
}
private int pageCount
{
get
{
return (this.total - 1) / this.maxResults;//总页数,记住都是从0开始的
}
}
private int lastPageStartAt
{
get
{
return pageCount * this.maxResults;//返回最末页的第0条的序号
}
}
private string query="";
protected string Query
{
get
{
return query;
}
set
{
this.query=value;
}
}
protected string Summary
{
get
{
if (this.total > 0)
return "共有结果<span style='color:red;'>' + this.total + '</span>,当前从第<span style='color:red;'>' + this.fromItem + '</span>条到第<span style='color:red;'>' + this.toItem + '</span>条,本次搜索耗时<span style='color:red;'>' + this.duration.TotalSeconds + '</span>秒'";
else
return "对不起,本次搜索没有找到任何结果";
}
}
}
}