lucene.NET 搜索引擎的开发实例

  /// <summary>
        /// 创建索引
        /// </summary>
        private void CreateIndexByData(HotLine12345.Model.KL_CONTENT_INFO model)
        {
            //索引文档保存位置     
            string indexPath = IndexDic;
            if (!System.IO.Directory.Exists(indexPath))
            {
                System.IO.Directory.CreateDirectory(indexPath);
            }
            FSDirectory directory = FSDirectory.Open(new DirectoryInfo(indexPath), new NativeFSLockFactory());
            //IndexReader:对索引库进行读取的类
            bool isExist = IndexReader.IndexExists(directory);
            //是否存在索引库文件夹以及索引库特征文件
            if (isExist)
            {
                //如果索引目录被锁定(比如索引过程中程序异常退出或另一进程在操作索引库),则解锁
                //Q:存在问题 如果一个用户正在对索引库写操作 此时是上锁的 而另一个用户过来操作时 将锁解开了 于是产生冲突 --解决方法后续
                if (IndexWriter.IsLocked(directory))
                {
                    IndexWriter.Unlock(directory);
                }
            }

            //创建向索引库写操作对象  IndexWriter(索引目录,指定使用盘古分词进行切词,最大写入长度限制)
            //补充:使用IndexWriter打开directory时会自动对索引库文件上锁
            IndexWriter writer = new IndexWriter(directory, new PanGuAnalyzer(), !isExist, IndexWriter.MaxFieldLength.UNLIMITED);
            try
            {
                ///
                ///写入开始
                /// 
                //new一篇文档对象 --一条记录对应索引库中的一个文档
                Document document = new Document();
                //向文档中添加字段  Add(字段,值,是否保存字段原始值,是否针对该列创建索引)
                //NOT_ANALYZED不分词且索引
                document.Add(new Field("id", model.KL_CONTENT_ID.ToString(), Field.Store.YES, Field.Index.NOT_ANALYZED));
                //Field.Store:表示是否保存字段原值。指定Field.Store.YES的字段在检索时才能用document.Get取出原值  
                //Field.Index.NOT_ANALYZED:指定不按照分词后的结果保存
                if (!string.IsNullOrEmpty(model.KL_CONTENT_TITLE))
                    document.Add(new Field("title", model.KL_CONTENT_TITLE, Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.WITH_POSITIONS_OFFSETS));
                document.Add(new Field("fileid", "0", Field.Store.YES, Field.Index.NOT_ANALYZED));
                if (!string.IsNullOrEmpty(model.KL_SORT_ID))
                    document.Add(new Field("type", Get_TypeName(Convert.ToInt32(model.KL_SORT_ID)), Field.Store.YES, Field.Index.NOT_ANALYZED));
                //Field.Index.ANALYZED:指定文章内容按照分词后结果保存 否则无法实现后续的模糊查询 
                //WITH_POSITIONS_OFFSETS:指示不仅保存分割后的词 还保存词之间的距离
                if (!string.IsNullOrEmpty(model.KL_CONTENT))
                    document.Add(new Field("content", model.KL_CONTENT, Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.WITH_POSITIONS_OFFSETS));
                //文档写入索引库
                writer.AddDocument(document);
                ///
                ///写入结束
                ///
                //会自动解锁
                writer.Close();
                //不要忘了Close,否则索引结果搜不到
                directory.Close();
            }
            catch (Exception ex)
            {
                writer.Close();
                //不要忘了Close,否则索引结果搜不到
                directory.Close();
            }
         }

//查询  public ActionResult Index()         {             List<HotLine12345.Model.KL_CONTENT_INFO> modelResult = new List<HotLine12345.Model.KL_CONTENT_INFO>();             string key = Request.Params["key"];             if (string.IsNullOrEmpty(key))             {                 modelResult = null;                 return View(modelResult);             }

            ViewBag.key = key;                         Dictionary<string, string> dic = new Dictionary<string, string>();             BooleanQuery bQuery = new BooleanQuery();

            string title = string.Empty;             string content = string.Empty;

            if (!string.IsNullOrEmpty(key))             {                 key = key.Trim();                 title = GetKeyWordsSplitBySpace(key);                 if (string.IsNullOrEmpty(title))                 {                     return View(modelResult);                 }                 QueryParser parse = new QueryParser("title", PanGuAnalyzer);                 Query query = parse.Parse(title);

                parse.SetDefaultOperator(QueryParser.Operator.OR);                 //BooleanClause用于表示布尔查询子句关系的类,包 括:MUST,MUST_NOT,SHOULD。 必须包含,不能包含,可以包含三种.                              bQuery.Add(query, BooleanClause.Occur.SHOULD);                 dic.Add("title", key);                 txtTitle = key;                                 //content = GetKeyWordsSplitBySpace(key);                 QueryParser parse2 = new QueryParser("content", PanGuAnalyzer);                 Query query2 = parse2.Parse(title);                 parse2.SetDefaultOperator(QueryParser.Operator.OR);                 bQuery.Add(query2, BooleanClause.Occur.SHOULD);                 dic.Add("content", key);                 txtContent = key;

                QueryParser parse3 = new QueryParser("type", PanGuAnalyzer);                 Query query3 = parse3.Parse(title);                 parse3.SetDefaultOperator(QueryParser.Operator.OR);                 bQuery.Add(query3, BooleanClause.Occur.SHOULD);

                /模糊查询                 Query query4 = new WildcardQuery(new Term("title", key + "*"));                 bQuery.Add(query4, BooleanClause.Occur.SHOULD);                                 Query query5 = new WildcardQuery(new Term("content", key + "*"));                 bQuery.Add(query5, BooleanClause.Occur.SHOULD);

            }             if (bQuery != null && bQuery.GetClauses().Length > 0)             {                 //搜索数据                 modelResult = GetSearchResult(bQuery, dic);             }                         return View(modelResult);         }

 #region 搜索查询         /// <summary>         /// 搜索引擎         /// </summary>         /// <param name="bQuery"></param>         private List<HotLine12345.Model.KL_CONTENT_INFO> GetSearchResult(BooleanQuery bQuery, Dictionary<string, string> dicKeywords)         {             List<HotLine12345.Model.KL_CONTENT_INFO> list = new List<HotLine12345.Model.KL_CONTENT_INFO>();             //FSDirectory directory = FSDirectory.Open(new DirectoryInfo(IndexDic), new NoLockFactory());             //IndexReader reader = IndexReader.Open(directory, true);             //IndexSearcher search = new IndexSearcher(reader);             try             {                 IndexSearcher search = new IndexSearcher(IndexDic, true);                 Stopwatch stopwatch = Stopwatch.StartNew();                 //SortField构造函数第三个字段true为降序,false为升序                 Sort sort = new Sort(new SortField("id", SortField.DOC, true));                 //采用默认排序,按匹配度排序                 TopDocs docs = search.Search(bQuery, (Lucene.Net.Search.Filter)null, PageSize * PageIndex);                 stopwatch.Stop();                 if (docs != null && docs.totalHits > 0)                 {                     lSearchTime = stopwatch.ElapsedMilliseconds;                     txtPageFoot = GetPageFoot(PageIndex, PageSize, docs.totalHits, "sabrosus");                     ViewData["txtPageFoot"] = txtPageFoot;                     for (int i = 0; i < docs.totalHits; i++)                     {                         if (i >= (PageIndex - 1) * PageSize && i < PageIndex * PageSize)                         {                             Document doc = search.Doc(docs.scoreDocs[i].doc);                             HotLine12345.Model.KL_CONTENT_INFO model = new HotLine12345.Model.KL_CONTENT_INFO();                             model.KL_CONTENT_TITLE = doc.Get("title").ToString();                             model.KL_CONTENT = doc.Get("content").ToString();                             model.KL_CONTENT_ID = Convert.ToInt32(doc.Get("id").ToString());                             model.KL_FILE = doc.Get("fileid").ToString();                             model.KL_SORT_ID = doc.Get("type").ToString();

                            list.Add(SetHighlighter(dicKeywords, model));                         }                     }                 }             }             catch (Exception ex)             {

            }             return list;         }

        /// <summary>         /// 处理关键字为索引格式         /// </summary>         /// <param name="keywords"></param>         /// <returns></returns>         private string GetKeyWordsSplitBySpace(string keywords)         {             PanGuTokenizer ktTokenizer = new PanGuTokenizer();             StringBuilder result = new StringBuilder();             ICollection<WordInfo> words = ktTokenizer.SegmentToWordInfos(keywords);             foreach (WordInfo word in words)             {                 if (word == null)                 {                     continue;                 }                 result.AppendFormat("{0}^{1}.0 ", word.Word, (int)Math.Pow(3, word.Rank));             }             return result.ToString().Trim();         }         /// <summary>         /// 分词器         /// </summary>         /// <param name="keywords"></param>         /// <returns></returns>         private List<string> GetKeyWords_List(string keywords)         {             PanGuTokenizer ktTokenizer = new PanGuTokenizer();             ICollection<WordInfo> words = ktTokenizer.SegmentToWordInfos(keywords);             List<string> list_word = words.Select(q => q.Word).ToList();

            return list_word;         }         /// <summary>         /// 设置关键字高亮         /// </summary>         /// <param name="dicKeywords">关键字列表</param>         /// <param name="model">返回的数据模型</param>         /// <returns></returns>         private HotLine12345.Model.KL_CONTENT_INFO SetHighlighter(Dictionary<string, string> dicKeywords, HotLine12345.Model.KL_CONTENT_INFO model)         {

            SimpleHTMLFormatter simpleHTMLFormatter = new PanGu.HighLight.SimpleHTMLFormatter("<font color=\"red\">", "</font>");             Highlighter highlighter = new PanGu.HighLight.Highlighter(simpleHTMLFormatter, new Segment());             highlighter.FragmentSize = 50;             string strTitle = string.Empty;             string strContent = string.Empty;             dicKeywords.TryGetValue("title", out strTitle);             dicKeywords.TryGetValue("content", out strContent);             if (!string.IsNullOrEmpty(strTitle))             {                 string str_content = highlighter.GetBestFragment(strTitle, model.KL_CONTENT_TITLE);                 if (!string.IsNullOrEmpty(str_content))                 {                     model.KL_CONTENT_TITLE = str_content;                 }                 else                 {                     model.KL_CONTENT_TITLE = strHtml_format(model.KL_CONTENT_TITLE, strTitle);                 }             }             if (!string.IsNullOrEmpty(strContent))             {                 model.KL_FILE = strHtml_format(model.KL_CONTENT, strTitle);                 string str_content = highlighter.GetBestFragment(strContent, model.KL_CONTENT);                 if (!string.IsNullOrEmpty(str_content))                 {                     model.KL_CONTENT = str_content;                 }                 else                 {                     model.KL_CONTENT = SubString(model.KL_CONTENT, 45);                 }             }

            return model;         }         private string strHtml_format(string str, string strTitle)         {             List<string> list_str = GetKeyWords_List(strTitle);             string formatStr = str.Replace("\n", "<br/>").Replace("\r", "<br/>").Replace("\r\n", "<br/>");             foreach (var item in list_str)             {                 formatStr = formatStr.Replace(item, "<font color='red'>" + item + "</font>");             }             return formatStr;         }         /// <summary>         /// 字符串截取         /// </summary>         /// <param name="str"></param>         /// <param name="subCount"></param>         /// <returns></returns>         private string SubString(string str, int subCount)         {             string NewStr = "";             if (str.Length > subCount)             {                 NewStr = str.Substring(0, subCount) + "...";             }             else             {                 NewStr = str;             }             return NewStr;         }

        /// <summary>         /// 是否覆盖索引         /// </summary>         private bool Cover         {             get             {                 if (Request.Form["cover"] != null)                 {                     if (Request.Form["cover"] == "1")                     {                         return true;                     }                     else                     {                         return false;                     }                 }                 else return true;             }         }

        /// <summary>         /// 分页页脚         /// </summary>         /// <param name="currentPageIndex">当前页</param>         /// <param name="pageSize">记录条数</param>         /// <param name="total">记录总数</param>         /// <param name="cssName">css样式名称</param>         /// <returns></returns>         private string GetPageFoot(int currentPageIndex, int pageSize, int total, string cssName)         {             currentPageIndex = currentPageIndex <= 0 ? 1 : currentPageIndex;             pageSize = pageSize <= 0 ? 10 : pageSize;             string options = string.Empty;             int pageCount = 0;//总页数             int pageVisibleCount = 10; // 显示数量             if (total % pageSize == 0)             {                 pageCount = total / pageSize;             }             else             {                 pageCount = total / pageSize + 1;             }             if (pageCount <= 1)             {                 return "";             }             //如果是整除的话,退后一页             StringBuilder sb = new StringBuilder();             sb.AppendFormat("<div class=\"page_left\">一页显示<select id=\"pageSize\" name=\"pageSize\" onchange =\"SC.Page.ChangeSize();\">{0}</select>&nbsp;条&nbsp;&nbsp;&nbsp;总共{1}条</div>", SetOption(pageSize), total);             sb.AppendFormat("<div class=\"page_right\">跳转到第<input type=\"text\" id=\"pageIndex\" name=\"pageIndex\" value=\"{0}\" />页<a href=\"javascript:void(0);\" class=\"easyui-linkbutton\" plain=\"true\" iconCls=\"icon-redo\" οnclick=\"SC.Page.GotoPage();\">Go</a>共<span id=\"pageCount\">" + pageCount + "</span>&nbsp;页</div><input type=\"hidden\" id=\"isSearch\" name=\"isSearch\" value=\"1\" />", currentPageIndex);

            sb.Append("<div class='" + cssName + "'>");// sbrosus分页样式,需要自己添加哇             if (currentPageIndex == 1 || total < 1)             {                 sb.Append("<span ><a href='javascript:void(0)'>首页</a></span>");                 sb.Append("<span ><a href='javascript:void(0)'>上一页</a></span>");             }             else             {                 sb.Append("<span><a οnclick=\"SC.Page.GetPage(1)\">首页</a></span>");                 sb.Append("<span><a οnclick=\"SC.Page.GetPage(" + (currentPageIndex - 1).ToString() + ")\">上一页</a></span>");             }             int i = 1;             int k = pageVisibleCount > pageCount ? pageCount : pageVisibleCount;             if (currentPageIndex > pageVisibleCount)             {                 i = currentPageIndex / pageVisibleCount * pageVisibleCount;                 k = (i + pageVisibleCount) > pageCount ? pageCount : (i + pageVisibleCount);             }             for (; i <= k; i++)//k*10防止k为负数             {                 if (i == currentPageIndex)                 {                     sb.AppendFormat("<span class='current' ><a href='javascript:void(0)'>{0}</a></span>&nbsp;", i);                 }                 else                 {                     sb.AppendFormat("<span><a οnclick=\"SC.Page.GetPage(" + i + ")\" >{0}</a></span>&nbsp;", i);                 }             }             if (currentPageIndex == pageCount || total < 1)             {                 sb.Append("<span ><a href='javascript:void(0)'>下一页</a></span>");                 sb.Append("<span ><a href='javascript:void(0)'>尾页</a></span>");             }             else             {                 sb.Append("<span><a οnclick=\"SC.Page.GetPage(" + (currentPageIndex + 1).ToString() + ")\">下一页</a></span>");                 sb.Append("<span><a οnclick=\"SC.Page.GetPage(" + pageCount + ")\">尾页</a></span></div>");             }             return sb.ToString();         }

        /// <summary>         /// 根据pagesize获取select标签         /// </summary>         /// <param name="pageSize"></param>         /// <returns></returns>         private string SetOption(int pageSize)         {             StringBuilder sb_options = new StringBuilder();             sb_options.AppendFormat("<option selected=\"selected\">{0}</option>", pageSize.ToString());             for (int i =1; i <7; i++)             {                 int creatIndex = (i * 50);                 if (pageSize != creatIndex)                     sb_options.AppendFormat("<option>{0}</option>", (creatIndex).ToString());             }             return sb_options.ToString();         }         #endregion

 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Bingo_BIG

你的鼓励是我最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值