mvc-百步飞剑-15
说明:Lucene.net的简单使用在以前的博客中做了简单介绍http://www.cnblogs.com/YK2012/p/6676942.html .其中所涉及的引用文件放置在对应的百度网盘的文件夹下.
1.1 添加搜索控制器(SearchController)
1.2 添加视图(index)
1.3 添加dll引用(Lucene.Net+PanGu+PanGu.Lucene.Analyzer+PanGu.HighLight)和字典并设置其属性为"复制到输出目录"
1.4 添加实体类(books)
1.5 根据实体类,通过T4模板生成相应的代码
1.6 配置Config文件
1.7 控制器中的代码
using BBFJ.OA.Model; using BBFJ.OA.WebApp.Models; using Lucene.Net.Analysis.PanGu; using Lucene.Net.Documents; using Lucene.Net.Index; using Lucene.Net.Search; using Lucene.Net.Store; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Web; using System.Web.Mvc; namespace BBFJ.OA.WebApp.Controllers { public class SearchController : Controller { // // GET: /Search/ IBLL.IBooksService BookInfoService { get;set;} public ActionResult Index() { return View(); } #region 01前台页面调用方法 public ActionResult SearchContent() { if (!String.IsNullOrEmpty(Request["btnSearch"])) { //搜索内容 List<ViewModelContent> list= SearchBookContent(); ViewData["list"] = list; return View("Index"); } else { CreateContent(); } return Content("ok"); } #endregion #region 02创建索引库 private void CreateContent() { //01创建分词后的内容放目录 string indexPath = @"E:\LuceneNet测试文件\索引文件"; FSDirectory directory = FSDirectory.Open(new DirectoryInfo(indexPath), new NativeFSLockFactory());//指定索引文件(打开索引目录) FS指的是就是FileSystem //判断目录是否存在(还可读取数据) bool isUpdate = IndexReader.IndexExists(directory); if (isUpdate) { //判断目录是否加锁 if (IndexWriter.IsLocked(directory)) { IndexWriter.Unlock(directory); } } //向索引库中写数据 盘古分词 加锁 IndexWriter writer = new IndexWriter(directory, new PanGuAnalyzer(), !isUpdate, Lucene.Net.Index.IndexWriter.MaxFieldLength.UNLIMITED); //查询数据 List<Books> list = BookInfoService.LoadEntities(c=>true).ToList(); foreach (var book in list) { //表示一篇文档。 Document document = new Document(); //书的编号 document.Add(new Field("id", book.Id.ToString(), Field.Store.YES, Field.Index.NOT_ANALYZED)); //书的标题 document.Add(new Field("title", book.Title, Field.Store.YES, Field.Index.ANALYZED, Lucene.Net.Documents.Field.TermVector.WITH_POSITIONS_OFFSETS)); //书的内容 document.Add(new Field("content", book.ContentDescription, Field.Store.YES, Field.Index.ANALYZED, Lucene.Net.Documents.Field.TermVector.WITH_POSITIONS_OFFSETS)); writer.AddDocument(document); } writer.Close();//会自动解锁。 directory.Close();//不要忘了Close,否则索引结果搜不到 } #endregion #region 03搜索 private List<ViewModelContent> SearchBookContent() { //定位到索引目录 string indexPath = @"E:\LuceneNet测试文件\索引文件"; //对用户输入的搜索条件进行拆分。因为很多地方都可能调用=>放置在Common中 List<string> listkw = Common.PanGuSplitWord.PanGuSplit(Request["txtSearchContent"]); 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 listkw) { query.Add(new Term("content", word)); } 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<ViewModelContent> ViewModelList = new List<ViewModelContent>(); for (int i = 0; i < docs.Length; i++) { ViewModelContent viewModel = new ViewModelContent(); int docId = docs[i].doc;//获得查询结果的id Document doc = searcher.Doc(docId);//根据id找到对应的文档详细信息 viewModel.Id = doc.Get("id"); viewModel.Title = doc.Get("title"); viewModel.Content = doc.Get("content"); ViewModelList.Add(viewModel); } return ViewModelList; } #endregion } }
1.7.1 需要对对用户输入的搜索条件进行拆分。因为很多地方都可能调用=>放置在Common中
using Lucene.Net.Analysis; using Lucene.Net.Analysis.PanGu; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; namespace BBFJ.OA.Common { public static class PanGuSplitWord { public static List<string> PanGuSplit(string msg) { Analyzer analyzer = new PanGuAnalyzer(); TokenStream tokenStream = analyzer.TokenStream("", new StringReader(msg)); Lucene.Net.Analysis.Token token = null; List<string> list = new List<string>(); while ((token = tokenStream.Next()) != null) { list.Add(token.TermText()); } return list; } } }
1.7.2 List<ViewModelContent>需要在Model中添加模型
using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace BBFJ.OA.WebApp.Models { public class ViewModelContent { public string Id { get; set; } public string Title { get; set; } public string Content { get; set; } } }
1.8 index中的方法
@{ Layout = null; } @using BBFJ.OA.WebApp.Models <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width" /> <title>商品搜素</title> </head> <body> <div> <form method="post" action="/Search/SearchContent"> <input type="text" name="txtSearchContent" style="width:400px"/> <input type="submit" value="搜索" name="btnSearch"/> <input type="submit" value="创建索引库" name="btnCreate"/> </form> <br /> <ul> @if (ViewData["list"]!=null) { foreach (ViewModelContent viewModel in (List<ViewModelContent>)ViewData["list"]) { <li>@viewModel.Title</li> <li>@viewModel.Content</li> } } </ul> </div> </body> </html>
运行结果

2.0 进一步美化
2.1 高亮变红
using Lucene.Net.Analysis; using Lucene.Net.Analysis.PanGu; using PanGu; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; namespace BBFJ.OA.Common { public static class PanGuSplitWord { public static List<string> PanGuSplit(string msg) { Analyzer analyzer = new PanGuAnalyzer(); TokenStream tokenStream = analyzer.TokenStream("", new StringReader(msg)); Lucene.Net.Analysis.Token token = null; List<string> list = new List<string>(); while ((token = tokenStream.Next()) != null) { list.Add(token.TermText()); } return list; } // /创建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); } } }
控制器中修改此处,高亮显示: viewModel.Content = Common.PanGuSplitWord.CreateHightLight(Request["txtSearchContent"], doc.Get("content"));
Index中使其不对其进行编码: <dd>@MvcHtmlString.Create(viewModel.Content)</dd>
运行效果


浙公网安备 33010602011771号