using System; using System.Data; using System.IO; using System.Text.RegularExpressions; using Lucene.Net.Analysis.Standard; using Lucene.Net.Documents; using Lucene.Net.QueryParsers; using Lucene.Net.Search; using Lucene.Net.Search.Highlight; using Lucene.Net.Analysis; using Lucene.Net.Index; using System.Configuration; namespace So ... { public class BaseSearch : System.Web.UI.Page ...{ 变量声明#region 变量声明 /**//// <summary> /// 搜索结果数据 /// </summary> public DataTable Results = new DataTable(); /**//// <summary> /// 开始索引 /// </summary> public int startAt; /**//// <summary> /// First item on page (user format). /// </summary> public int fromItem; /**//// <summary> /// Last item on page (user format). /// </summary> public int toItem; /**//// <summary> /// 搜索的结果总数 /// </summary> public int total; /**//// <summary> /// 搜索所用时间 /// </summary> public TimeSpan duration; /**//// <summary> /// 每页显示结果项条数 /// </summary> public int maxResults = 10; /**//// <summary> /// 是否启用网页缓存功能 /// </summary> public bool EnableCache; /**//// <summary> /// 缓存URL /// </summary> public string CacheURL; /**//// <summary> /// 索引文件存放的路径 /// </summary> public string IndexDiectory; private string m_Query; public Lucene.Net.Store.Directory dir; #endregion 变量声明 取得查询目标索引的缓存#region 取得查询目标索引的缓存 public void GetIndexDir(string IndexKey, string IndexDiectory) ...{ //object obj = Cache[IndexKey]; //if (obj != null) //{ // dir = (Lucene.Net.Store.Directory)obj; //} //else //{ // dir = new Lucene.Net.Store.RAMDirectory(IndexDiectory); // Cache.Insert(IndexKey, dir, null, DateTime.Now.AddMinutes(2), TimeSpan.Zero); //} dir = new Lucene.Net.Store.RAMDirectory(IndexDiectory); } #endregion 得到定长的字符串#region 得到定长的字符串 /**//// <summary> /// 得到定长的字符串 /// </summary> /// <param name="p_Text">原字符串</param> /// <param name="p_Length">长度</param> /// <param name="p_ExtraText">多余部分显示字符</param> /// <returns></returns> public string GetLengthText(string p_Text, int p_Length, string p_ExtraText) ...{ return (p_Text.Length > p_Length) ? (p_Text.Substring(0, 45) + p_ExtraText) : p_Text; } #endregion 取得两个参数中的最小值#region 取得两个参数中的最小值 /**//// <summary> /// 取得两个参数中的最小值 /// </summary> /// <param name="first">参数一</param> /// <param name="second">参数二</param> /// <returns>最小值</returns> public int smallerOf(int first, int second) ...{ return first < second ? first : second; } #endregion 检测开始位置#region 检测开始位置 /**//// <summary> /// Initializes startAt value. Checks for bad values. /// </summary> /// <returns></returns> public int initStartAt() ...{ try ...{ int sa = Convert.ToInt32(this.Request.Params["start"]); // too small starting item, return first page if (sa < 0) return 0; // too big starting item, return last page if (sa >= total - 1) ...{ return lastPageStartsAt; } return sa; } catch ...{ return 0; } } #endregion 最后一页的第一项#region 最后一页的第一项 /**//// <summary> /// First item of the last page /// </summary> public int lastPageStartsAt ...{ get ...{ return pageCount * maxResults; } } public int pageCount ...{ get ...{ return (total - 1) / maxResults; // floor } } #endregion 取得高亮连接#region 取得高亮连接 /**//// <summary> /// 取得高亮连接 /// </summary> /// <param name="p_Body">处理内容</param> /// <param name="p_KeyWords">关键词</param> /// <returns></returns> public string SimpleHighLighter(string p_Body, string p_KeyWords, string p_Before, string p_After, int p_MaxLength) ...{ string[] KeyWords = p_KeyWords.Trim().Split(' '); //if (p_Body.Length > p_MaxLength) //{ // if (p_Body.IndexOf(KeyWords[0]) > 10) // { // try // { // if ((p_Body.Length - 10) > p_MaxLength) // p_Body = p_Body.Substring(p_Body.IndexOf(KeyWords[0]) - 10, p_MaxLength) + "..."; // else // p_Body = p_Body.Substring(p_Body.IndexOf(KeyWords[0]) - 10) + "..."; // } // catch // { } // } // else // p_Body = p_Body.Substring(0, p_MaxLength) + "..."; //} for (int i = 0; i < KeyWords.Length; i++) ...{ p_Body = p_Body.Replace(KeyWords[i], p_Before + KeyWords[i] + p_After); } return p_Body; } #endregion 属性#region 属性 /**//// <summary> /// 查询关键词 /// </summary> public string Query ...{ get ...{ return m_Query; } set ...{ m_Query = value; } } #endregion }} using System; using System.Data; using System.IO; using System.Text.RegularExpressions; using Lucene.Net.Analysis.Standard; using Lucene.Net.Documents; using Lucene.Net.QueryParsers; using Lucene.Net.Search; using Lucene.Net.Search.Highlight; using Lucene.Net.Analysis; using Lucene.Net.Index; using System.Configuration; namespace So.News ... { public class NewsSearch : BaseSearch ...{ public NewsSearch() ...{ this.IndexDiectory = ConfigurationManager.AppSettings["NewsIndexPath"]; } 处理搜索并将信息转换为可显示结果数据源#region 处理搜索并将信息转换为可显示结果数据源 /**//// <summary> /// Does the search and stores the information about the results. /// </summary> public void search() ...{ // 索引目录 //string indexDirectory = Server.MapPath(ConfigurationSettings.AppSettings["EnableCache"] ); //创建一个Searcher用于搜索 //记录查询开始的时间 DateTime start = DateTime.Now; this.GetIndexDir("HDC.News", IndexDiectory); IndexSearcher searcher = new IndexSearcher(dir); //从"body"字段搜索 //Console.WriteLine(this.Query); Lucene.Net.Analysis.Analyzer OneAnalyzer = new StandardAnalyzer(); QueryParser parser = new QueryParser("newsContent", OneAnalyzer); Query query = parser.Parse(this.Query); //创建结果记录集 //定义字段 this.Results.Columns.Add("ArticleID", typeof(int)); this.Results.Columns.Add("ArticleClassID", typeof(int)); this.Results.Columns.Add("className", typeof(string)); this.Results.Columns.Add("titleImg", typeof(string)); this.Results.Columns.Add("updateTime", typeof(DateTime)); this.Results.Columns.Add("source", typeof(string)); this.Results.Columns.Add("title", typeof(string)); this.Results.Columns.Add("summary", typeof(string)); Sort sort = new Sort(new SortField("ArticleID", SortField.DOC, true)); //Hits是搜索结果记录集,不过是Lucene自己的格式,需要格式化成标准输出 Hits hits = searcher.Search(query, sort); //结果个数 this.total = hits.Length(); /**/////创建高亮显示 //Highlighter highlighter = new Highlighter(new SimpleHTMLFormatter("<font color="#C60A00">", "</font>"), new QueryScorer(query)); //highlighter.TextFragmenter = new SimpleFragmenter(160); //highlighter.MaxDocBytesToAnalyze = 256; // initialize startAt this.startAt = initStartAt(); // how many items we should show - less than defined at the end of the results int resultsCount = smallerOf(total, this.maxResults + this.startAt); for (int i = startAt; i < resultsCount; i++) ...{ Document doc = hits.Doc(i); DataRow row = this.Results.NewRow(); row["ArticleID"] = Convert.ToInt32(doc.Get("ArticleID")); row["ArticleClassID"] = Convert.ToInt32(doc.Get("ArticleClassID")); string summary = doc.Get("summary"); row["summary"] = this.SimpleHighLighter(summary, this.Query,"<font color="#C60A00">", "</font>",226); row["className"] = doc.Get("className"); row["titleImg"] = doc.Get("titleImg"); row["updateTime"] = Convert.ToDateTime(doc.Get("updateTime")); row["source"] = doc.Get("source"); row["title"] = doc.Get("title"); this.Results.Rows.Add(row); } searcher.Close(); // result information this.fromItem = startAt + 1; this.toItem = smallerOf(startAt + maxResults, total); //记录查询使用的时间 this.duration = DateTime.Now - start; } #endregion 页面底航连接#region 页面底航连接 /**//// <summary> /// 页面底航连接 /// </summary> public DataTable Paging ...{ get ...{ int pageNumber = (startAt + maxResults - 1) / maxResults; DataTable dt = new DataTable(); dt.Columns.Add("html", typeof(string)); //增加第一页链接 DataRow tar = dt.NewRow(); if (startAt >= maxResults) tar["html"] = "<EM><a href="/News/?q=" + Server.UrlEncode(this.Query) + "&start=" + (startAt - maxResults) + ""><IMG src="images/b_pre.gif"></a></EM>"; else tar["html"] = "<EM><IMG src="images/b_pre.gif"></EM>"; dt.Rows.Add(tar); int previousPagesCount = 7; DataRow ar = dt.NewRow(); ar["html"] = pagingItemHtml(startAt, pageNumber + 1, false); dt.Rows.Add(ar); for (int i = pageNumber - 1; i >= 0 && i >= pageNumber - previousPagesCount; i--) ...{ int step = i - pageNumber; DataRow r = dt.NewRow(); r["html"] = pagingItemHtml(startAt + (maxResults * step), i + 1, true); dt.Rows.InsertAt(r, 1); } int nextPagesCount = 8; for (int i = pageNumber + 1; i <= pageCount && i <= pageNumber + nextPagesCount; i++) ...{ int step = i - pageNumber; DataRow r = dt.NewRow(); r["html"] = pagingItemHtml(startAt + (maxResults * step), i + 1, true); dt.Rows.Add(r); } //增加第一页链接 DataRow far = dt.NewRow(); if (pageNumber < pageCount) far["html"] = "<EM><a class="blue1" href="/News/?q=" + Server.UrlEncode(this.Query) + "&start=" + (startAt + maxResults) + ""><IMG src="images/b_nextpage.gif"></a></EM>"; else far["html"] = "<EM><IMG src="images/b_nextpage.gif"></EM>"; dt.Rows.Add(far); return dt; } } 页面连接列表#region 页面连接列表 /**//// <summary> /// 页面连接列表 /// </summary> /// <param name="start">开始</param> /// <param name="number">显示数量</param> /// <param name="active">活动</param> /// <returns></returns> public string pagingItemHtml(int start, int number, bool active) ...{ if (active) return "<VAR><a href="/News/?q=" + Server.UrlEncode(this.Query) + "&start=" + start + "">" + number + "</a></VAR>"; else return "<VAR class=on>" + number + "</VAR>"; } #endregion #endregion }}