zoukankan      html  css  js  c++  java
  • (转)lucene.net和(pangu)盘古分词 搜索引擎的简单实现

    本文转载自:http://blog.csdn.net/dongdongleng/article/details/6058416

    这篇文章是介绍lucene.net和盘古分词的简单的实现调用  。建立索引,搜索,盘古分词的基类如下:

    [c-sharp] view plaincopy
    1. using System;  
    2. using System.Data;  
    3. using System.Configuration;  
    4. using System.Linq;  
    5. using System.Web;  
    6. using System.Web.Security;  
    7. using System.Web.UI;  
    8. using System.Web.UI.HtmlControls;  
    9. using System.Web.UI.WebControls;  
    10. using System.Web.UI.WebControls.WebParts;  
    11. using System.Xml.Linq;  
    12. using Lucene.Net.Index;  
    13. using Lucene.Net.Documents;  
    14. using Lucene.Net.QueryParsers;  
    15. using Lucene.Net.Analysis;  
    16. using Lucene.Net.Search;  
    17. using Lucene.Net.Analysis.Standard;  
    18. using PanGu;  
    19. using Lucene.Net.Analysis.PanGu;  
    20. using StringBulider;  
    21. using System.Text;  
    22. using System.Collections;  
    23. using System.Collections.Generic;  
    24.   
    25. /// <summary>  
    26. ///辅导资料的搜索逻辑 的摘要说明  
    27. /// </summary>  
    28. public class DataSearch  
    29. {  
    30.     public DataSearch()  
    31.     {  
    32.         //  
    33.         //TODO: 在此处添加构造函数逻辑  
    34.         //  
    35.     }  
    36.      A_DB_Conn db = null;  
    37.     string index = System.Web.HttpContext.Current.Server.MapPath("~/Gongxin/DataIndex");//索引路径  
    38.     string wordPath = System.Web.HttpContext.Current.Server.MapPath("~/Dictionaries");//字典路径  
    39.     //用于存储检索出数据总数  
    40.     private int _count;  
    41.   
    42.     public int Count  
    43.     {  
    44.         get { return _count; }  
    45.         set { _count = value; }  
    46.     }  
    47.     //搜索关键字  
    48.     private string _keyword;  
    49.   
    50.     public string KeyWord  
    51.     {  
    52.         get { return _keyword;}  
    53.         set{_keyword = value;}  
    54.     }  
    55.     //搜索时间  
    56.     private double  _time;  
    57.     public double Time  
    58.     {  
    59.         get { return _time; }  
    60.         set { _time = value; }  
    61.     }  
    62.     /// <summary>  
    63.     /// 得到数据结果集  
    64.     /// </summary>  
    65.     /// <returns></returns>  
    66.     public DataTable GetDS()  
    67.     {  
    68.         db = new A_DB_Conn();  
    69.         string sql = "select  N_id,N_title,N_datetime,N_Content from N_Newinfo where N_ifkping=1 and N_id=12 order by N_datetime desc";  
    70.         DataTable dataTable = null;  
    71.         try  
    72.         {  
    73.             dataTable = db.GetDataSet(sql).Tables[0];  
    74.         }  
    75.         catch  
    76.         {  
    77.             dataTable = null;  
    78.         }  
    79.         finally  
    80.         {  
    81.             db.close();  
    82.             db.Dispose();  
    83.         }  
    84.         return dataTable;  
    85.     }  
    86.   
    87.     /// <summary>  
    88.     /// 添加索引域  
    89.     /// </summary>  
    90.     /// <param name="writer"></param>  
    91.     /// <param name="dataTable"></param>  
    92.     public void AddDocument(IndexWriter writer, DataTable dataTable)  
    93.     {  
    94.         for (int i = 0; i < dataTable.Rows.Count; i++)  
    95.         {  
    96.             Document doc = new Document();  
    97.             doc.Add(new Field("ID", dataTable.Rows[i]["N_id"].ToString(),Field.Store.YES,Field.Index.TOKENIZED));  
    98.             doc.Add(new Field("N_title",StringCheck.SqlQueryDecode(dataTable.Rows[i]["N_title"].ToString()),Field.Store.YES,Field.Index.TOKENIZED));  
    99.             doc.Add(new Field("N_datetime", dataTable.Rows[i]["N_datetime"].ToString(),Field.Store.YES,Field.Index.TOKENIZED));            
    100.             if (StringCheck.SqlQueryDecode(dataTable.Rows[i]["N_Content"].ToString()).Length > 100)  
    101.             {  
    102.                 doc.Add(new Field("N_Content", StringCheck.SqlQueryDecode(dataTable.Rows[i]["N_Content"].ToString()).Replace("<p>","").Replace("</p>","").Substring(0, 200), Field.Store.YES, Field.Index.TOKENIZED));  
    103.             }  
    104.             else  
    105.             {  
    106.                 doc.Add(new Field("N_Content", StringCheck.SqlQueryDecode(dataTable.Rows[i]["N_Content"].ToString()).Replace("<p>""").Replace("</p>"""), Field.Store.YES, Field.Index.TOKENIZED));  
    107.             }  
    108.             writer.AddDocument(doc);  
    109.         }  
    110.     }  
    111.   
    112.     /// <summary>  
    113.     /// 建立索引  
    114.     /// </summary>  
    115.     public void Index()  
    116.     {  
    117.         PanGu.Segment.Init();  
    118.         PanGuAnalyzer analyzer = new PanGuAnalyzer();  
    119.         IndexWriter writer = new IndexWriter(index, analyzer, true);  
    120.         DataTable dataTable = GetDS();  
    121.         AddDocument(writer, dataTable);  
    122.         writer.Optimize();  
    123.         writer.Close();          
    124.     }  
    125.   
    126.     /// <summary>  
    127.     /// 对药搜索的词进行分词  
    128.     /// </summary>  
    129.     /// <param name="keyWords">要收索的词</param>  
    130.     /// <param name="ktTokenizer">分词对象</param>  
    131.     /// <returns>分词后的结果</returns>  
    132.     public string GetKeyWordSplitBySpace(string keyWords, PanGuTokenizer ktTokenizer)  
    133.     {  
    134.         StringBuilder builder = new StringBuilder();  
    135.         ICollection<WordInfo> words = ktTokenizer.SegmentToWordInfos(keyWords);  
    136.         foreach(WordInfo word in words)  
    137.         {  
    138.             if (word == null)  
    139.             {  
    140.                 continue;  
    141.             }  
    142.             KeyWord = KeyWord + word+",";             
    143.             builder.AppendFormat("{0}^{1}",word.Word,(int)Math.Pow(3,word.Rank));  
    144.         }  
    145.         KeyWord = KeyWord.Substring(0, KeyWord.Length - 1);  
    146.         return builder.ToString().Trim();  
    147.     }  
    148.   
    149.     /// <summary>  
    150.     /// 检索信息  
    151.     /// </summary>  
    152.     /// <param name="keyWord">检索关键字</param>  
    153.     /// <param name="pageNumber">当前第几条</param>  
    154.     /// <param name="pageSize">每页显示的条数</param>  
    155.     /// <returns></returns>  
    156.     public string Search(string keyWord, int pageNumber, int pageSize)  
    157.     {  
    158.         string word = GetKeyWordSplitBySpace(keyWord, new PanGuTokenizer());  
    159.           
    160.         IndexSearcher search = new IndexSearcher(index);  
    161.         StringBuilder builder = new StringBuilder();  
    162.         PanGuAnalyzer analyzer = new PanGuAnalyzer(true);  
    163.         //多字段搜索字段  
    164.         MultiFieldQueryParser parser = new MultiFieldQueryParser(new string[] { "N_title" },analyzer);  
    165.         //分词  
    166.         Query query = parser.Parse(word);  
    167.         Hits hits = search.Search(query);  
    168.         Count = hits.Length();  
    169.         int num = 0;//记录每页最后一条  
    170.         if (Count < pageNumber + pageSize)  
    171.         {  
    172.             num = Count;  
    173.         }  
    174.         else  
    175.         {  
    176.             num = pageSize + pageNumber;  
    177.         }  
    178.         DateTime  begin = DateTime.Now;  
    179.         for (int i = pageNumber; i < num; i++)  
    180.         {  
    181.             Document doc = hits.Doc(i);  
    182.             //创建HTMLFormatter,参数为高亮搜索词的HTML代码  
    183.             PanGu.HighLight.SimpleHTMLFormatter simpleHTMLFormatter = new PanGu.HighLight.SimpleHTMLFormatter("<font color='red'>""</font>");  
    184.             //创建高亮,输入HTML代码和 盘古对象Semgent  
    185.             PanGu.HighLight.Highlighter highter = new PanGu.HighLight.Highlighter(simpleHTMLFormatter, new Segment());  
    186.             //设置每个摘要字段的字符数  
    187.             highter.FragmentSize = 200;  
    188.             string title = highter.GetBestFragment(keyWord, doc.Get("N_title"));              
    189.             builder.Append("<div class='sea_h_list'>");  
    190.             if (!string.IsNullOrEmpty(title))  
    191.             {  
    192.                 builder.Append("<h2><a href="D_NewBody.aspx?gxjy=" + UrlEncrpt.Encrypt(doc.Get("ID")) + "" mce_href="D_NewBody.aspx?gxjy=" + UrlEncrpt.Encrypt(doc.Get("ID")) + "" target='_blank'>" + highter.GetBestFragment(keyWord, doc.Get("N_title")) + "</a></h2>");  
    193.             }  
    194.             else  
    195.             {  
    196.                 builder.Append("<h2>" + doc.Get("N_title") + "</h2>");  
    197.             }             
    198.             builder.Append(doc.Get("N_Content"));            
    199.             DateTime time = Convert.ToDateTime(doc.Get("N_datetime"));  
    200.             builder.Append("<div>"+time.ToString("yyyy-MM-dd")+"</div>");  
    201.             builder.Append("</div>");  
    202.   
    203.         }  
    204.         DateTime end = DateTime.Now;  
    205.         double  ts = (end - begin).TotalMilliseconds;  
    206.         Time =ts / 1000.000;  
    207.         search.Close();//关闭检索器  
    208.         return builder.ToString();  
    209.     }  
    210. }  

    前台可以用一个button调用一个button事件来生成索引

    前台生成索引事件如下。

    [c-sharp:nogutter] view plaincopy
    1. protected void Button1_Click(object sender, EventArgs e)  
    2.     {  
    3.         search = new NewsSearch();  
    4.         search.Index();  
    5.         Response.Write("<Script>alert('索引生成成功!')</Script>");  
    6.     }  

    索引生成成功后,就可以进行搜索了,本人实现搜索的功能时调用了AspNetPager分页控件,具体的搜索的方法如下:

    [c-sharp:nogutter] view plaincopy
    1. public void GetInfoList(string keyWord)  
    2.   {  
    3.       try  
    4.       {  
    5.           search = new NewsSearch();  
    6.           Stopwatch sw = new Stopwatch();  
    7.           sw.Start();  
    8.           InfoList = search.Search(keyWord, (this.AspNetPager1.CurrentPageIndex - 1) * this.AspNetPager1.PageSize, this.AspNetPager1.PageSize);  
    9.           sw.Stop();  
    10.           time = (sw.ElapsedMilliseconds / 1000.000).ToString();//显示所用搜索时间  
    11.           if (InfoList.Trim().Length == 0)  
    12.           {  
    13.               InfoList = "<div class='rig01_center red'>暂无搜索信息。</div>";  
    14.           }  
    15.           this.AspNetPager1.RecordCount = search.Count;  
    16.           count = search.Count.ToString();//搜索的条数  
    17.           strkeyWord = search.KeyWord;//显示搜索关键字  
    18.             
    19.       }  
    20.       catch  
    21.       {  
    22.           Response.Redirect("404.html");  
    23.       }  
    24.   
    25.   }  

    其中 Stopwatch使用了计算搜索所用的时间,将它复制到time 全局变量中,count 全局变量时用来存储搜索的条数。

    搜索出来数据后,前台页面用<%=count%><%=time%> <%=InfoList%>

    调用即可。

    前台显示效果: 

    本文只是简单的实现了lucene.net 和盘古分词,仅供大家学习,有不足的地方还请见谅,有疑问随时联系,谢谢!

  • 相关阅读:
    2015生命之旅---第三站象山之行
    我的八年程序之路(四)程序路上的新起点
    2015生命之旅---第二站长沙杭州
    2015生命之旅---第一站重庆
    我的八年程序之路(三)为了理想放弃高薪
    锋友分享:国行和非国行iPhone的送修需知
    iPhone被盗后续更新二:被换机!已取机!没扣住新机!怎么找新机呢?事发半年后跟进...
    iPhone被盗后续更新一:怎么找老机
    iPhone被盗后怎么?这篇文章只办针对iOS7后的系统
    四个小诀窍 告诉你雪景怎么拍才能更好看
  • 原文地址:https://www.cnblogs.com/wpcnblog/p/2394061.html
Copyright © 2011-2022 走看看