zoukankan      html  css  js  c++  java
  • Lucene.net应用

    1、加入盘古分词方法

      /// <summary>
           /// 对输入的搜索的条件进行分词
           /// </summary>
           /// <param name="str"></param>
           /// <returns></returns>
           public static List<string> GetPanGuWord(string str)
           {
               Analyzer analyzer = new PanGuAnalyzer();
               TokenStream tokenStream = analyzer.TokenStream("", new StringReader(str));
               Lucene.Net.Analysis.Token token = null;
               List<string> list = new List<string>();
               while ((token = tokenStream.Next()) != null)
               {
                  list.Add(token.TermText());
               }
               return list;
           }
    View Code

    2、创建视图显示的MODEL(ViewModel)

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    
    namespace CZBK.ItcastOA.WebApp.Models
    {
        public class ViewSarchContentModel
        {
            public string Id { get; set; }
            public string Title { get; set; }
            public string Content { get; set; }
        }
    }
    View Code

    3、根据数据库表中字段创建索引

           /// <summary>
            /// 负责向写数据
            /// </summary>
            private void CreateSearchIndex()
            {
                string indexPath = @"C:lucenedir";//注意和磁盘上文件夹的大小写一致,否则会报错。将创建的分词内容放在该目录下。
                FSDirectory directory = FSDirectory.Open(new DirectoryInfo(indexPath), new NativeFSLockFactory());//指定索引文件(打开索引目录) FS指的是就是FileSystem
                bool isUpdate = IndexReader.IndexExists(directory);//IndexReader:对索引进行读取的类。该语句的作用:判断索引库文件夹是否存在以及索引特征文件是否存在。
                if (isUpdate)
                {
                    //同时只能有一段代码对索引库进行写操作。当使用IndexWriter打开directory时会自动对索引库文件上锁。
                    //如果索引目录被锁定(比如索引过程中程序异常退出),则首先解锁(提示一下:如果我现在正在写着已经加锁了,但是还没有写完,这时候又来一个请求,那么不就解锁了吗?这个问题后面会解决)
                    if (IndexWriter.IsLocked(directory))
                    {
                        IndexWriter.Unlock(directory);
                    }
                }
                IndexWriter writer = new IndexWriter(directory, new PanGuAnalyzer(), !isUpdate, Lucene.Net.Index.IndexWriter.MaxFieldLength.UNLIMITED);//向索引库中写索引。这时在这里加锁。
               List<Books>list= BookService.LoadEntities(c=>true).ToList();
    
               foreach (Books bookModel in list)
               {
                   writer.DeleteDocuments(new Term("Id",bookModel.Id.ToString()));
                   Document document = new Document();//表示一篇文档。
                   //Field.Store.YES:表示是否存储原值。只有当Field.Store.YES在后面才能用doc.Get("number")取出值来.Field.Index. NOT_ANALYZED:不进行分词保存
                   document.Add(new Field("Id",bookModel.Id.ToString(), Field.Store.YES, Field.Index.NOT_ANALYZED));
    
                   //Field.Index. ANALYZED:进行分词保存:也就是要进行全文的字段要设置分词 保存(因为要进行模糊查询)
    
                   //Lucene.Net.Documents.Field.TermVector.WITH_POSITIONS_OFFSETS:不仅保存分词还保存分词的距离。
                   document.Add(new Field("Title", bookModel.Title, Field.Store.YES, Field.Index.ANALYZED, Lucene.Net.Documents.Field.TermVector.WITH_POSITIONS_OFFSETS));
    
                   document.Add(new Field("Content", bookModel.ContentDescription, Field.Store.YES, Field.Index.ANALYZED, Lucene.Net.Documents.Field.TermVector.WITH_POSITIONS_OFFSETS));
    
                   writer.AddDocument(document);
               }
                
                writer.Close();//会自动解锁。
                directory.Close();//不要忘了Close,否则索引结果搜不到
    
            }
    View Code

    4、搜索

           private List<ViewSarchContentModel> SearchBookContent()
            {
                string indexPath = @"C:lucenedir";
                List<string> kw =Common.WebCommon.GetPanGuWord(Request["txtContent"]);
    
                FSDirectory directory = FSDirectory.Open(new DirectoryInfo(indexPath), new NoLockFactory());
                IndexReader reader = IndexReader.Open(directory, true);
                IndexSearcher searcher = new IndexSearcher(reader);
                //搜索条件
                PhraseQuery query = new PhraseQuery();
                foreach (string word in kw)//先用空格,让用户去分词,空格分隔的就是词“计算机   专业”
                {
                    query.Add(new Term("Content", word));
                }
                //query.Add(new Term("body","语言"));--可以添加查询条件,两者是add关系.顺序没有关系.
                //query.Add(new Term("body", "大学生"));
                //query.Add(new Term("body", kw));//body中含有kw的文章
                query.SetSlop(100);//多个查询条件的词之间的最大距离.在文章中相隔太远 也就无意义.(例如 “大学生”这个查询条件和"简历"这个查询条件之间如果间隔的词太多也就没有意义了。)
                //TopScoreDocCollector是盛放查询结果的容器
                TopScoreDocCollector collector = TopScoreDocCollector.create(1000, true);
                searcher.Search(query, null, collector);//根据query查询条件进行查询,查询结果放入collector容器
                ScoreDoc[] docs = collector.TopDocs(0, collector.GetTotalHits()).scoreDocs;//得到所有查询结果中的文档,GetTotalHits():表示总条数   TopDocs(300, 20);//表示得到300(从300开始),到320(结束)的文档内容.
                //可以用来实现分页功能
    
                List<ViewSarchContentModel> list = new List<ViewSarchContentModel>();
                for (int i = 0; i < docs.Length; i++)
                {
                    ViewSarchContentModel viewModel = new ViewSarchContentModel();
                    //
                    //搜索ScoreDoc[]只能获得文档的id,这样不会把查询结果的Document一次性加载到内存中。降低了内存压力,需要获得文档的详细内容的时候通过searcher.Doc来根据文档id来获得文档的详细内容对象Document.
                    
                    
                    int docId = docs[i].doc;//得到查询结果文档的id(Lucene内部分配的id)
                    Document doc = searcher.Doc(docId);//找到文档id对应的文档详细信息
                    viewModel.Id = doc.Get("Id");
                    viewModel.Title = doc.Get("Title");
                    viewModel.Content =Common.WebCommon.CreateHightLight(Request["txtContent"], doc.Get("Content"));//搜索内容关键字高亮显示
                    list.Add(viewModel);
                    
                }
                return list;
            }
    View Code

    5、返回给VIEW

     public ActionResult SearchContent()
            {
                if (!string.IsNullOrEmpty(Request["btnSearch"]))
                {
                   List<ViewSarchContentModel>list= SearchBookContent();
                   ViewData["searchList"] = list;
                   ViewData["searchWhere"] = Request["txtContent"];
                   return View("Index");
                }
                else
                {
                    CreateSearchIndex();
                }
                return Content("ok");
            }
    View Code

    6、视图表现

    @{
        Layout = null;
    }
    @using CZBK.ItcastOA.WebApp.Models
    <!DOCTYPE html>
    <html>
    <head>
        <meta name="viewport" content="width=device-width" />
        <title>文档搜索</title>
        <script src="~/Scripts/jquery-1.7.1.min.js"></script>
        <style type="text/css">
          .search-text2{ display:block; width:528px; height:26px; line-height:26px; float:left; margin:3px 5px; border:1px solid; font-family:'Microsoft Yahei'; font-size:14px;}
          .search-btn2{width:102px; height:32px; line-height:32px; cursor:pointer; border:0px; background-color:#d6000f;font-family:'Microsoft Yahei'; font-size:16px;color:#f3f3f3;}
          .search-list{width:600px; overflow:hidden; margin:10px 20px 0px 20px;}
           .search-list dt{font-family:'Microsoft Yahei'; font-size:16px; line-height:20px; margin-bottom:7px; font-weight:normal;}
           .search-list .search-detail{font-size:12px; color:#666666;margin-bottom:5px; font-family:Arial;line-height:16px;}
           .search-list dt a{color:#2981a9;}
        </style>
     
    </head>
    <body>
    
          <!-- JiaThis Button BEGIN -->
    <script type="text/javascript" >
        var jiathis_config = {
            data_track_clickback: true,
            showClose: true,
            hideMore: false
        }
    </script>
    <script type="text/javascript" src="http://v3.jiathis.com/code/jiathis_r.js?uid=1986459&type=left&btn=l.gif&move=0" charset="utf-8"></script>
    <!-- JiaThis Button END -->
        <div>
            <form method="get" action="/Search/SearchContent">
                <input type="text" value="@ViewData["searchWhere"]" name="txtContent" autocomplete="off" class="search-text2"/>
                <input type="submit" value="搜一搜" name="btnSearch" class="search-btn2" />
                <input type="submit" value="创建索引库" name="btnCreate" />
            </form>
    
            <dl class="search-list">
            @if (ViewData["searchList"] != null)
            {
                foreach (ViewSarchContentModel viewModel in (List<ViewSarchContentModel>)ViewData["searchList"])
                {
                    <dt><a href="/Book/ShowDetail/?id=@viewModel.Id"> @viewModel.Title</a></dt>
                 <dd class="search-detail">@MvcHtmlString.Create(viewModel.Content)</dd>
                }
            }
                </dl>
    
        </div>
    </body>
    </html>
    View Code

     

    改变输入框、按钮样式,高亮显示

     <style type="text/css">
          .search-text2{ display:block; width:528px; height:26px; line-height:26px; float:left; margin:3px 5px; border:1px solid; font-family:'Microsoft Yahei'; font-size:14px;}
          .search-btn2{width:102px; height:32px; line-height:32px; cursor:pointer; border:0px; background-color:#d6000f;font-family:'Microsoft Yahei'; font-size:16px;color:#f3f3f3;}
          .search-list{width:600px; overflow:hidden; margin:10px 20px 0px 20px;}
           .search-list dt{font-family:'Microsoft Yahei'; font-size:16px; line-height:20px; margin-bottom:7px; font-weight:normal;}
           .search-list .search-detail{font-size:12px; color:#666666;margin-bottom:5px; font-family:Arial;line-height:16px;}
           .search-list dt a{color:#2981a9;}
        </style>

    盘古分词的高亮组件PanGu.HighLight.dll,引用高亮显示组件

        // /创建HTMLFormatter,参数为高亮单词的前后缀
           public static string CreateHightLight(string keywords, string Content)
           {
               PanGu.HighLight.SimpleHTMLFormatter simpleHTMLFormatter =
                new PanGu.HighLight.SimpleHTMLFormatter("<font color="red">", "</font>");
               //创建Highlighter ,输入HTMLFormatter 和盘古分词对象Semgent
               PanGu.HighLight.Highlighter highlighter =
               new PanGu.HighLight.Highlighter(simpleHTMLFormatter,
               new Segment());
               //设置每个摘要段的字符数
               highlighter.FragmentSize = 150;
               //获取最匹配的摘要段
               return highlighter.GetBestFragment(keywords, Content);
    
           }

    keywords搜索关键词,Content搜索结果

     viewModel.Content =Common.WebCommon.CreateHightLight(Request["txtContent"], doc.Get("Content"));//搜索内容关键字高亮显示

    视图中

    <dd class="search-detail">@MvcHtmlString.Create(viewModel.Content)</dd>

    @输出进行了编码,用@会输出HTML标签

    Lucene每次生成索引不会删除、覆盖以前生成的,会造成搜索时搜索到重复的记录,所以生成前先要删除一次(实质没有删除文件,只是给文件个删除标记)

    writer.DeleteDocuments(new Term("Id",bookModel.Id.ToString()));

    搜索页面采用<form method="get" .............>,并采用静态页面:有利于网站推广

    分享到

    加<script src="~/Scripts/jquery-1.7.1.min.js"></script>

    并将以下代码放入body
    <!-- JiaThis Button BEGIN -->
    <script type="text/javascript" >
    var jiathis_config = {
    data_track_clickback: true,
    showClose: true,
    hideMore: false
    }
    </script>
    <script type="text/javascript" src="http://v3.jiathis.com/code/jiathis_r.js?uid=1986459&type=left&btn=l.gif&move=0" charset="utf-8"></script>
    <!-- JiaThis Button END -->

  • 相关阅读:
    20155313 杨瀚 《网络对抗技术》实验九 Web安全基础
    20155313 杨瀚 《网络对抗技术》实验八 Web基础
    20155313 杨瀚 《网络对抗技术》实验七 网络欺诈防范
    20155313 杨瀚 《网络对抗技术》实验六 信息搜集与漏洞扫描
    20155313 杨瀚 《网络对抗技术》实验五 MSF基础应用
    20155313 杨瀚 《网络对抗技术》实验四 恶意代码分析
    20155313 杨瀚 《网络对抗技术》实验三 免杀原理与实践
    20155313 杨瀚 《网络对抗技术》实验二 后门原理与实践
    20155313 杨瀚 《网络对抗技术》实验一 PC平台逆向破解(5)M
    20155313 2017-2018-1 《信息安全系统设计基础》课程总结
  • 原文地址:https://www.cnblogs.com/ecollab/p/6164127.html
Copyright © 2011-2022 走看看