using System; using System.Data; using System.Configuration; using System.Collections; using System.Web; using System.IO; using System.Web.Security; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Web.UI.HtmlControls; using System.Text.RegularExpressions; using Lucene.Net.Search; using Lucene.Net.Index; using Lucene.Net.QueryParsers; using Lucene.Net.Analysis.Standard; using Lucene.Net.Search.Highlight; using Lucene.Net.Documents; using System.Data.SqlClient; using Lucene.Net.Analysis.Cn; public partial class Search : System.Web.UI.Page { /// <summary> /// 搜索返回的结果集 /// </summary> protected DataTable Results = new DataTable(); /// <summary> /// 搜索返回的结果总数 /// </summary> private int total; /// <summary> /// 搜索的结果每页显示多少记录条数 /// </summary> private readonly int maxResults = 10; /// <summary> /// 本次搜索所花费的时间 /// </summary> private TimeSpan duration; /// <summary> /// 本次搜索是从哪条数据开始的,这个东西很重要,通过他基本上可以得到一切 /// </summary> private int startAt; /// <summary> /// 本页显示的数据是从哪条开始的,他总是startAt+1 /// </summary> private int fromItem; /// <summary> /// 本页显示的数据记录到哪条结束 /// </summary> private int toItem; protected void Page_Load(object sender, EventArgs e) { //给搜索按牛注册下隐藏事件 // this.Page.ClientScript.RegisterHiddenField("__EVENTTARGET","buttonSearch"); if (!IsPostBack) { if (this.Query != null) { search(); DataBind(); } else { Response.Redirect("./");//如果没有传入查询字符则定向到开始页面 } } } protected void search() { DateTime start = DateTime.Now;//搜索的开始时间 //得到索引所在的目录,我们在上个console程序里把索引放到了index目录下 string indexDirectory = Server.MapPath("index"); //创建个索引搜索器 IndexSearcher searcher = new IndexSearcher(indexDirectory); string[] b = this.Query.Split(' '); BooleanQuery m_BooleanQuery = new BooleanQuery(); //分词并解析索引的text字段以便搜索,多条件检索 for (int i = 0; i < b.Length; i++) { Query thisQuery = QueryParser.Parse(b[i], "text", new ChineseAnalyzer()); m_BooleanQuery.Add(thisQuery, true, false); } //为要绑定输出到页面的results建立几列 this.Results.Columns.Add("path",typeof(string)); this.Results.Columns.Add("sample",typeof(string)); this.Results.Columns.Add("title",typeof(string)); //开始搜索 Hits hits = searcher.Search(m_BooleanQuery); //得到搜索返回的记录总数 this.total = hits.Length(); //创建一个高亮 QueryHighlightExtractor highlighter = new QueryHighlightExtractor(m_BooleanQuery, new ChineseAnalyzer(), "<b>", "</b>"); //初始化startAt,以便得到要显示的结果集 this.startAt = initStartAt(); //得到当前页要显示的记录数量,包括以前所有页的记录数,这样把他与this.startAt结合就能够很好的知道当前页要显示的记录数了 int resultsCount = smallOf(this.total,this.startAt+this.maxResults); //开始循环得到当前页要显示的记录ex string pp = ""; //for (int i = this.startAt; i < resultsCount; i++) //for (int i = this.startAt ; i <resultsCount; i+exit+) for (int i = this.total - this.startAt-1; i >= this.total - resultsCount; i--) { //得到每一行Hits的Document,因为Hits的没一行都是个Document对象 Document doc = hits.Doc(i); //得到doc里面的列path的值 string path = doc.Get("path"); pp += path + ","; //再得到这个路径在web程序的路径,我们原来把文档放到了web根目录的documents目录下的 string location = Server.MapPath(@"documents/" + path); //用StreamReader读取文档,因为我们不能够直接从索引中得到text字段的值,因为我们建立索引的时候没有存储他的 string plainText; //using (StreamReader sr = new StreamReader(location, System.Text.Encoding.Default)) //{ // plainText = ParseHtml(sr.ReadToEnd()); //} //为结果集DataTable,Results添加个新行 } if (pp.Length > 0) pp = pp.Substring(0, pp.Length - 1); //Response.Write(pp); //string ppp = pp.Split(','); //string kk = ""; //if (kk.Length > 0) // kk = kk.Substring(0, kk.Length - 1); //for (int i = this.startAt; i < resultsCount; i++) // kk += ppp[i] + ","; if (pp.Length > 0) { SqlConnection conn = new SqlConnection("server=.;uid=sa;pwd=liugehao;database=yaowanggu;"); //取出10条记录 SqlCommand cmd = new SqlCommand("select z_id,z_name,z_lx,z_pzwh,z_sccs,z_jx,z_gg,z_yfyl,z_zsqy,z_dltj,z_tgzc,z_dwmc,z_lxdh,z_lxr from ywg_zhaoshang where z_id in (" + pp + ") order by z_id desc", conn); conn.Open(); SqlDataReader sdr = cmd.ExecuteReader(System.Data.CommandBehavior.CloseConnection); while (sdr.Read()) { DataRow dr = this.Results.NewRow(); dr["title"] = sdr[1].ToString(); dr["path"] = @"documents/" + sdr[0].ToString(); dr["sample"] = highlighter.GetBestFragment(sdr[1].ToString() + sdr[2].ToString() + sdr[3].ToString() + sdr[4].ToString() + sdr[5].ToString() + sdr[6].ToString() + sdr[7].ToString() + sdr[8].ToString() + sdr[9].ToString() + sdr[10].ToString() + sdr[11].ToString() + sdr[12].ToString() + sdr[13].ToString(),100); //把行添加进DataTable this.Results.Rows.Add(dr); } conn.Close(); } //循环完毕,关闭搜索 searcher.Close(); //搜索花费多少时间 this.duration = DateTime.Now - start; //给fromItem赋值,他总是startAt+1 this.fromItem = this.startAt + 1; //给toItem赋值 this.toItem = smallOf(this.total,this.startAt+this.maxResults); } private string ParseHtml(string html) { string temp = Regex.Replace(html,"<[^>]*>",""); return temp.Replace(" "," "); } /// <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="Search.aspx?q=" + HttpUtility.UrlEncode(this.Query) + "&start=" + (pageNumber + 1) * this.maxResults + "" mce_href="Search.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="Search.aspx?q="+HttpUtility.UrlEncode(this.Query)+"&start="+start+"" mce_href="Search.aspx?q="+HttpUtility.UrlEncode(this.Query)+"&start="+start+"">"+number+"</a>"; } else { return "<span style="font-weight:bold;" mce_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条的序号 } } protected string Query { get { string query = HttpUtility.UrlDecode(this.Request.Params["q"]); if (query == string.Empty) return null; return query; } } protected string Summary { get { if (this.total > 0) return "共有结果<span style="color:red;" mce_style="color:red;">' + this.total + '</span>,当前从第<span style="color:red;" mce_style="color:red;">' + this.fromItem + '</span>条到第<span style="color:red;" mce_style="color:red;">' + this.toItem + '</span>条,本次搜索耗时<span style="color:red;" mce_style="color:red;">' + this.duration.TotalSeconds + '</span>秒'; else return "对不起,本次搜索没有找到任何结果"; } } protected void buttonSearch_Click(object sender, EventArgs e) { this.Response.Redirect("Search.aspx?q="+HttpUtility.UrlEncode(this.textboxQuery.Text)); } } 文章来自学IT网:http://www.xueit.com/html/2009-02/21_613_00.html