摘要:本文主要向大家介绍了C#编程之一步步开发自己的博客 .NET版(5、Lucenne.Net ),通过具体的内容向大家展示,希望对大家学习C#编程有所帮助。
本文主要向大家介绍了C#编程之一步步开发自己的博客 .NET版(5、Lucenne.Net ),通过具体的内容向大家展示,希望对大家学习C#编程有所帮助。
今天来分析下 嗨-博客 中的搜索功能。搜索功能在个人网站里面要有这么个东西,但又不是特别重要。所以我们需要有,可以不用太深入了解,毕竟我们不是专门做搜索这块的。
所以,我打算把搜索分两块。一块是,用Lucene.Net实现站内搜索。一块是利用第三方搜索引擎来 实现站内搜索。
Lucene.net是Lucene的.net移植版本,是一个开源的全文检索引擎开发包,即它不是一个完整的全文检索引擎,而是一个全文检索引擎的架构,提供了完整的查询引擎和索引引擎。开发人员可以基于Lucene.net实现全文检索的功能。Lucene.net是Apache软件基金会赞助的开源项目,基于Apache License协议。Lucene.net并不是一个爬行搜索引擎,也不会自动地索引内容。我们得先将要索引的文档中的文本抽取出来,然后再将其加到Lucene.net索引中。标准的步骤是先初始化一个Analyzer、打开一个IndexWriter、然后再将文档一个接一个地加进去。一旦完成这些步骤,索引就可以在关闭前得到优化,同时所做的改变也会生效。这个过程可能比开发者习惯的方式更加手工化一些,但却在数据的索引上给予你更多的灵活性,而且其效率也很高。(来源百度百科)
其实 在之前 我也是接触到过Lucene.net,那也是自己 做的个小玩意(博客备份小工具3) 瞎折腾的。但是 这次打算迁移到这个系统中,不知怎么的 报错了。可能是这次用的是 .net 4.5。Lucene这东西太高深,我也没打算深究。于是 在网上收索了一把,资料还挺多的。《lucene.net 3.0.3、结合盘古分词进行搜索的小例子(分页功能)》 我随意看了下,这里有个 帮助类 挺不错的,也还符合 我这样想要的效果。这里来分析下这个帮助类。
1.首先创建索引。
IndexWriter writer = new IndexWriter(directory_luce, analyzer, false, IndexWriter.MaxFieldLength.LIMITED);Document doc = new Document();doc.Add(new Field(name, value, Field.Store.YES, Field.Index.NOT_ANALYZED));writer.AddDocument(doc);
这里的
directory_luce 是索引创建路径
analyzer 分析器
value 是对应 存入索引额名字和值
2.从索引里面搜索
string[] fileds = { "title", "content" };//查询字段 QueryParser parser = null; parser = new MultiFieldQueryParser(version, fileds, analyzer);//多个字段查询 Query query = parser.Parse(keyword); int n = 1000; IndexSearcher searcher = new IndexSearcher(directory_luce, true);//true-表示只读 TopDocs docs = searcher.Search(query, (Filter)null, n); if (docs == null || docs.TotalHits == 0) { return null; } else { List list = new List(); int counter = 1; foreach (ScoreDoc sd in docs.ScoreDocs)//遍历搜索到的结果 { try { Document doc = searcher.Doc(sd.Doc); int id = int.Parse(doc.Get("id")); string title = doc.Get("title"); string content = doc.Get("content"); string blogTag = doc.Get("blogTag"); string url = doc.Get("url"); int flag = int.Parse(doc.Get("flag")); int clickQuantity = int.Parse(doc.Get("clickQuantity")); string createdate = doc.Get("createdate"); PanGu.HighLight.SimpleHTMLFormatter simpleHTMLFormatter = new PanGu.HighLight.SimpleHTMLFormatter("", ""); PanGu.HighLight.Highlighter highlighter = new PanGu.HighLight.Highlighter(simpleHTMLFormatter, new PanGu.Segment()); highlighter.FragmentSize = 50; content = highlighter.GetBestFragment(keyword, content); string titlehighlight = highlighter.GetBestFragment(keyword, title); if (titlehighlight != "") title = titlehighlight; list.Add(new SearchResult(title, content, url, blogTag, id, clickQuantity, flag)); } catch (Exception ex) { Console.WriteLine(ex.Message); } counter++; } return list;
3.完整代码
public class PanGuLuceneHelper { private PanGuLuceneHelper() { } #region 单一实例 private static PanGuLuceneHelper _instance = null; /// /// 单一实例 /// public static PanGuLuceneHelper instance { get { if (_instance == null) _instance = new PanGuLuceneHelper(); return _instance; } } #endregion #region 00一些属性和参数 #region Lucene.Net的目录-参数 private Lucene.Net.Store.Directory _directory_luce = null; /// /// Lucene.Net的目录-参数 /// public Lucene.Net.Store.Directory directory_luce { get { if (_directory_luce == null) _directory_luce = Lucene.Net.Store.FSDirectory.Open(directory); return _directory_luce; } } #endregion #region 索引在硬盘上的目录 private System.IO.DirectoryInfo _directory = null; /// /// 索引在硬盘上的目录 /// public System.IO.DirectoryInfo directory { get { if (_directory == null) { string dirPath = AppDomain.CurrentDomain.BaseDirectory + "SearchIndex"; if (System.IO.Directory.Exists(dirPath) == false) _directory = System.IO.Directory.CreateDirectory(dirPath); else _directory = new System.IO.DirectoryInfo(dirPath); } return _directory; } } #endregion #region 分析器 private Analyzer _analyzer = null; /// /// 分析器 /// public Analyzer analyzer { get { { _analyzer = new Lucene.Net.Analysis.PanGu.PanGuAnalyzer();// } return _analyzer; } } #endregion #region 版本号枚举类 private static Lucene.Net.Util.Version _version = Lucene.Net.Util.Version.LUCENE_30; /// /// 版本号枚举类 /// public Lucene.Net.Util.Version version { get { return _version; } } #endregion #endregion #region 01创建索引 /// /// 创建索引(先删 后更新) /// /// /// public bool CreateIndex(List datalist) { IndexWriter writer = null; try { writer = new IndexWriter(directory_luce, analyzer, false, IndexWriter.MaxFieldLength.LIMITED);//false表示追加(true表示删除之前的重新写入) } catch { writer = new IndexWriter(directory_luce, analyzer, true, IndexWriter.MaxFieldLength.LIMITED);//false表示追加(true表示删除之前的重新写入) } foreach (SearchResult data in datalist) { writer.DeleteDocuments(new Term("id", data.id.ToString()));//新增前 删除 不然会有重复数据 CreateIndex(writer, data); } writer.Optimize(); writer.Dispose(); return true; } public bool CreateIndex(SearchResult data) { List datalist = new List(); datalist.Add(data); return CreateIndex(datalist); } public bool CreateIndex(IndexWriter writer, SearchResult data) { try { if (data == null) return false; Document doc = new Document(); Type type = data.GetType();//assembly.GetType("Reflect_test.PurchaseOrderHeadManageModel", true, true); //命名空间名称 + 类名 //创建类的实例 //object obj = Activator.CreateInstance(type, true); //获取公共属性 PropertyInfo[] Propertys = type.GetProperties(); for (int i = 0; i < Propertys.Length; i++) { //Propertys[i].SetValue(Propertys[i], i, null); //设置值 PropertyInfo pi = Propertys[i]; string name = pi.Name; object objval = pi.GetValue(data, null); string value = objval == null ? "" : objval.ToString(); //值 if (name == "id" || name == "flag")//id在写入索引时必是不分词,否则是模糊搜索和删除,会出现混乱 { doc.Add(new Field(name, value, Field.Store.YES, Field.Index.NOT_ANALYZED));//id不分词 } else { doc.Add(new Field(name, value, Field.Store.YES, Field.Index.ANALYZED)); } } writer.AddDocument(doc); } catch (System.IO.FileNotFoundException fnfe) { throw fnfe; } return true; } #endregion #region 02在title和content字段中查询数据 /// /// 在title和content字段中查询数据 /// /// /// public List Search(string keyword) { string[] fileds = { "title", "content" };//查询字段 QueryParser parser = null; parser = new MultiFieldQueryParser(version, fileds, analyzer);//多个字段查询 Query query = parser.Parse(keyword); int n = 1000; IndexSearcher searcher = new IndexSearcher(directory_luce, true);//true-表示只读 TopDocs docs = searcher.Search(query, (Filter)null, n); if (docs == null || docs.TotalHits == 0) { return null; } else { List list = new List(); int counter = 1; foreach (ScoreDoc sd in docs.ScoreDocs)//遍历搜索到的结果 { try { Document doc = searcher.Doc(sd.Doc); int id = int.Parse(doc.Get("id")); string title = doc.Get("title"); string content = doc.Get("content"); string blogTag = doc.Get("blogTag"); string url = doc.Get("url"); int flag = int.Parse(doc.Get("flag")); int clickQuantity = int.Parse(doc.Get("clickQuantity")); string createdate = doc.Get("createdate"); PanGu.HighLight.SimpleHTMLFormatter simpleHTMLFormatter = new PanGu.HighLight.SimpleHTMLFormatter("", ""); PanGu.HighLight.Highlighter highlighter = new PanGu.HighLight.Highlighter(simpleHTMLFormatter, new PanGu.Segment()); highlighter.FragmentSize = 50; content = highlighter.GetBestFragment(keyword, content); string titlehighlight = highlighter.GetBestFragment(keyword, title); if (titlehighlight != "") title = titlehighlight;
本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标编程语言C#.NET频道!
您输入的评论内容中包含违禁敏感词
我知道了
请输入正确的手机号码
请输入正确的验证码
您今天的短信下发次数太多了,明天再试试吧!
我们会在第一时间安排职业规划师联系您!
您也可以联系我们的职业规划师咨询:
版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
沪公网安备 31011502005948号