⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 search.aspx.cs

📁 小型搜索软件的源代码
💻 CS
字号:
/*
 * Copyright 2005 dotlucene.net
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

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 ShootSearch.Helper;
using System.Configuration;

namespace Searcher
{
	/// <summary>
	/// Summary description for WebForm1.
	/// </summary>
	public class Search : System.Web.UI.Page
	{
		/// <summary>
		/// Search results.
		/// </summary>
		protected DataTable Results = new DataTable();

		/// <summary>
		/// First item on page (index format).
		/// </summary>
		private int startAt;

		/// <summary>
		/// First item on page (user format).
		/// </summary>
		private int fromItem;

		/// <summary>
		/// Last item on page (user format).
		/// </summary>
		private int toItem;

		/// <summary>
		/// Total items returned by search.
		/// </summary>
		private int total;

		/// <summary>
		/// Time it took to make the search.
		/// </summary>
		private TimeSpan duration;

		/// <summary>
		/// How many items can be showed on one page.
		/// </summary>
		private readonly int maxResults = 10;

		private bool EnableCache ;
		private string CacheURL;
		private string IndexDiectory ;
		private string m_Query;

        protected System.Web.UI.WebControls.TextBox TextBoxQuery;
		protected System.Web.UI.WebControls.Repeater Repeater1;
		protected System.Web.UI.WebControls.Label LabelSummary;
		protected System.Web.UI.WebControls.Repeater Repeater2;
		protected System.Web.UI.WebControls.Button ButtonSearch;
	
		#region Page_Load
		/// <summary>
		/// Page_Load
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void Page_Load(object sender, System.EventArgs e)
		{
			// Press ButtonSearch on enter
			Page.RegisterHiddenField("__EVENTTARGET", "ButtonSearch");
			try
			{
				Query = System.Web.HttpUtility.UrlDecode(this.Request["q"]).Trim();
			}
			catch
			{
				Query = null;
			}

			if (!IsPostBack)
			{
//				EnableCache = Convert.ToBoolean(ConfigurationSettings.AppSettings["EnableCache"]) ;
//				CacheURL = ConfigurationSettings.AppSettings["Cache"];
//				IndexDiectory =  Server.MapPath(ConfigurationSettings.AppSettings["index"] );
				EnableCache =true ;
				CacheURL = "\\dotlucene\\cache";
				IndexDiectory =  Server.MapPath("index") ;
				if (this.Query != null && Query!="") 
				{
					search();
					DataBind();
				}
			}
		}
		#endregion

		#region Web Form Designer generated code
		override protected void OnInit(EventArgs e)
		{
			//
			// CODEGEN: This call is required by the ASP.NET Web Form Designer.
			//
			InitializeComponent();
			base.OnInit(e);
		}
		
		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{    
			this.ButtonSearch.Click += new System.EventHandler(this.ButtonSearch_Click);
			this.Load += new System.EventHandler(this.Page_Load);

		}
		#endregion
		
		#region Does the search and stores the information about the results.

		/// <summary>
		/// Does the search and stores the information about the results.
		/// </summary>
		private void search()
		{
			DateTime start = DateTime.Now;

			// 索引目录
			//string indexDirectory = Server.MapPath(ConfigurationSettings.AppSettings["EnableCache"] );  
			//创建一个Searcher用于搜索
			IndexSearcher searcher = new IndexSearcher(IndexDiectory); 
			//从"body"字段搜索
			Console.WriteLine(this.Query);
			Query query = QueryParser.Parse(this.Query, "body", new StandardAnalyzer()); 

			//创建结果记录集
			//定义字段
			this.Results.Columns.Add("title", typeof(string));
			this.Results.Columns.Add("sample", typeof(string));
			this.Results.Columns.Add("info", typeof(string));
			this.Results.Columns.Add("url", typeof(string));

			//Hits是搜索结果记录集,不过是Lucene自己的格式,需要格式化成标准输出
			Hits hits = searcher.Search(query);
			//结果个数
			this.total = hits.Length();

			//创建高亮显示
			Formatter formatter = new SimpleHTMLFormatter("<font color=#C60A00>","</font>");
			Highlighter highlighter = new Highlighter(formatter ,new QueryScorer(query));
			highlighter.TextFragmenter= new SimpleFragmenter(40);
			highlighter.MaxDocBytesToAnalyze = 512 ;
			
			// 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++) 
			{

				// get the document from index
				Document doc = hits.Doc(i);

				// get the document filename
				// we can't get the text from the index because we didn't store it there
				string url = doc.Get("url");
				
				// this is the place where the documents are stored on the server

				// instead, load it from the original location
				string plainText;

				plainText = doc.Get("body");
				StandardAnalyzer analyzer= new StandardAnalyzer();
				TokenStream tokenStream = analyzer.TokenStream("body", new StringReader(plainText));
				// Get 3 best fragments and seperate with a "..."
				
				string result ;
				try
				{
					result = highlighter.GetBestFragments(tokenStream,plainText,3, "...");
				}
				catch
				{
					Console.WriteLine(plainText.Length);
					//if(plainText.Length>500)
					//	plainText = plainText.Substring(0,500);
					result = this.SimpleHighLighter( plainText ,this.Query,"<font color=#C60A00>","</font>"
						,128) ;

					
					//result = highlighter.GetBestFragments(tokenStream,plainText,3, "...");
				}
				// create a new row with the result data
				DataRow row = this.Results.NewRow();
				row["title"] = doc.Get("name");

				//坐下面一行显示页面相关信息的
				string info= Tools.GetLengthText(url,45,"...");
				double length = Convert.ToDouble(doc.Get("length"))/ 1024.0 ;
				string strLength = length.ToString();
				if(strLength.Length >4 ) 
					strLength = strLength.Substring(0,4);
				info += " " + doc.Get("created") + " " + strLength + "k" ; 
				if(EnableCache)
				{
					info += " <a href = \"cache.aspx?cache=" + System.Web.HttpUtility.UrlEncode( this.CacheURL + doc.Get("cache") ) 
						+  "&url=" + System.Web.HttpUtility.UrlEncode(doc.Get("url")) + "&key=" 
						+ System.Web.HttpUtility.UrlEncode(this.Query) + " \" class=\"link\" target=\"_blank\" >射日快照</a>" 
						+ doc.Get("modified") ;
				}
				//各字段赋值
				row["info"] = info;
				row["url"] = url;
				row["sample"] = result;

				this.Results.Rows.Add(row);
			} 
			searcher.Close();

			// result information
			this.duration = DateTime.Now - start;
			this.fromItem = startAt + 1;
			this.toItem = smallerOf(startAt + maxResults, total);
		}
		#endregion

		#region Returns the smaller value of parameters.
		/// <summary>
		/// Returns the smaller value of parameters.
		/// </summary>
		/// <param name="first"></param>
		/// <param name="second"></param>
		/// <returns></returns>
		private int smallerOf(int first, int second)
		{
			return first < second ? first : second;
		}
		#endregion

		#region  Page links
		/// <summary>
		/// Page links. DataTable might be overhead but there used to be more fields in previous version so I'm keeping it for now.
		/// </summary>
		protected DataTable Paging
		{
			get
			{
				// pageNumber starts at 1
				int pageNumber = (startAt + maxResults - 1) / maxResults;

				DataTable dt = new DataTable();
				dt.Columns.Add("html", typeof(string));

				DataRow ar = dt.NewRow();
				ar["html"] = pagingItemHtml(startAt, pageNumber + 1, false);
				dt.Rows.Add(ar);

				int previousPagesCount = 4;
				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, 0);
				}

				int nextPagesCount = 4;
				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);
				}
				return dt;
			}
		}

		#endregion

		#region Prepares HTML of a paging item

		/// <summary>
		/// Prepares HTML of a paging item (bold number for current page, links for others).
		/// </summary>
		/// <param name="start"></param>
		/// <param name="number"></param>
		/// <param name="active"></param>
		/// <returns></returns>
		private string pagingItemHtml(int start, int number, bool active)
		{

			if (active)
				return "<a href=\"Search.aspx?q=" + this.Query + "&start=" + start + "\">" + number + "</a>";
			else
				return "<b>" + number + "</b>";
		}
		#endregion

		#region Prepares the string with seach summary information.
		/// <summary>
		/// Prepares the string with seach summary information.
		/// </summary>
		protected string Summary
		{
			get
			{
				if (total > 0)
					return "Results <b>" + this.fromItem + " - " + this.toItem + "</b> of <b>" + this.total + "</b> for <b>" + this.Query + "</b>. (" + this.duration.TotalSeconds + " seconds)";
				return "No results found";
			}
		}
		#endregion

		#region Return search query or null if not provided.
		/// <summary>
		/// Return search query or null if not provided.
		/// </summary>
		protected string Query
		{
			get 
			{
				return m_Query ;
//				string query = System.Web.HttpUtility.HtmlDecode(this.Request["q"]);
//				if (query == String.Empty)
//					return null;
//				return query;
			}
			set
			{
				m_Query = value ;
			}
		}
		#endregion
		
		#region Initializes startAt value. Checks for bad values.
		/// <summary>
		/// Initializes startAt value. Checks for bad values.
		/// </summary>
		/// <returns></returns>
		private 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 How many pages are there in the results.
		/// <summary>
		/// How many pages are there in the results.
		/// </summary>
		private int pageCount
		{
			get 
			{
				return (total - 1) / maxResults; // floor
			}
		}

		#endregion

		#region First item of the last page

		/// <summary>
		/// First item of the last page
		/// </summary>
		private int lastPageStartsAt
		{
			get
			{
				return pageCount * maxResults;
			}
		}
		#endregion

		#region This should be replaced with a direct client-side get
		/// <summary>
		/// This should be replaced with a direct client-side get
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void ButtonSearch_Click(object sender, System.EventArgs e)
		{
			this.Response.Redirect("Search.aspx?q=" + this.TextBoxQuery.Text);
		}

		#endregion

		#region Very simple, inefficient, and memory consuming HTML parser. Take a look at Demo/HtmlParser in DotLucene package for a better HTML parser.
		
		/// <summary>
		/// Very simple, inefficient, and memory consuming HTML parser. Take a look at Demo/HtmlParser in DotLucene package for a better HTML parser.
		/// </summary>
		/// <param name="html"></param>
		/// <returns></returns>
		private string parseHtml(string html)
		{
			string temp = Regex.Replace(html, "<[^>]*>", "");
			return temp.Replace("&nbsp;", " ");
		}

		#endregion

		#region SimpleHighLighter

		/// <summary>
		/// SimpleHighLighter
		/// </summary>
		/// <param name="p_Body"></param>
		/// <param name="p_KeyWords"></param>
		/// <returns></returns>
		private 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) + "...";

				//p_Body = p_Body.Substring(0,80) + "...";
			
			}


			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
		private string SimpleHighLightHelper(string p_Body, string p_KeyWords)
		{
			return "";
			
		}
		#endregion

	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -