两年前就开始使用Lucene.Net 了,不过那个时候使用的是Lucene.Net,不多那时候使用的是Lucene.Net 3.03,+PanGu分词,那时候盘古分词还不适配 3.03版本,后来看了痞子一毛 的这个教程,这个也是我最先学习全文检索的方面的知识了,最近我的网站也要使用搜索了,于是我看了很多的全文检索工具,有百度的站内检索,看着还不错,但是就是不好使用,有的就是搜索不出来(可能是我不会配置吧,我看博客园中有人说挺好用的),还看了Elasticsearch和Solr,solr太难配置,所以放弃了,Elasticsearch挺好用的,本地都配置好了,但是具体了解了下,太吃内存了,我现在使用的是很小的一个服务器,所以不方便使用。本来看了看阿里云的云 Elasticsearch和开放搜索,但是对于我来说还是太贵了,所以就使用简单又好用的Lucene.Net 了。
Lucene.Net 4.8版本相对于3.03版本有了很多的修改,而且根据开发者介绍,4.8的测试版都要比3.03的更加稳定,所以决定使用Lucene.Net 4.8版本,追求进步嘛!
由于自己作死,又好久没有做这个搜索了,所以耗费了好久才可以简单的使用,只有搜索和高亮,连中文分词都没有,以后再慢慢改进吧。
用于测试的类是新建的News类
public class News { public int Id { get; set; } public string Url { get; set; } public string Docno { get; set; } public string Title { get; set; } public string Content { get; set; } }
//批量添加 public void BuildNewsIndex(Listnewes) { if (newes == null) throw new ArgumentNullException(); foreach (var book in newes) { Document movieDocument = BuildNewsDocument(book); indexWriter.UpdateDocument(new Term(book.Docno.ToString()), movieDocument );//这里的book.Docno作为一个相当于数据库ID的存在,当存在的时候更新 } indexWriter.Flush(true, true);//每次必须关闭,不然搜索不到添加的数据 indexWriter.Commit(); }
private Document BuildNewsDocument(News news) { Document doc = new Document { new StoredField("id", news.Id), new TextField("title", news.Title, Field.Store.YES), new TextField("url", news.Url, Field.Store.YES), new TextField("docno", news.Docno, Field.Store.YES), new TextField("content", news.Content, Field.Store.YES), }; return doc; }
private static readonly LuceneVersion MatchVersion = LuceneVersion.LUCENE_48; private readonly IndexWriter indexWriter; private readonly SearcherManager searcherManager; private readonly QueryParser queryParser; private readonly Analyzer analyzer; public Class1(Directory indexDirectory) { analyzer = new StandardAnalyzer(MatchVersion); queryParser = new MultiFieldQueryParser(MatchVersion, new[] { "title", "author", "cnt" }, analyzer);//title等都是要分词的项 indexWriter = new IndexWriter(indexDirectory, new IndexWriterConfig(MatchVersion, analyzer)); searcherManager = new SearcherManager(indexWriter, true, null); }
public ListSearch(string queryString) { int resultsPerpage = 10; Query query = BuildQuery(queryString); searcherManager.MaybeRefreshBlocking(); IndexSearcher sercher = searcherManager.Acquire(); TopDocs topDocs = sercher.Search(query, resultsPerpage); List list = new List (); foreach (ScoreDoc sd in topDocs.ScoreDocs) //遍历搜索到的结果 { News news = new News(); Document doc = sercher.Doc(sd.Doc); news.Title = doc.Get("title"); news.Url = doc.Get("url"); news.Docno = doc.Get("docno"); news.Content = doc.Get("content"); SimpleHTMLFormatter sht = new SimpleHTMLFormatter("", "");//关键字高亮的左右标签 Highlighter highlighter = new Highlighter( sht, new SimpleHTMLEncoder(), new QueryScorer(query)); news.Title = highlighter.GetBestFragment(analyzer, "title", news.Title);//这里用于处理关键字高亮 news.Content = highlighter.GetBestFragment(analyzer, "title", news.Content); list.Add(news); } return list; } private Query BuildQuery(string queryString) => queryParser.Parse(queryString); public void Dispose() { indexWriter?.Dispose(); searcherManager?.Dispose(); }
Lucene.Net 4.8的GitHub 地址:https://github.com/apache/lucenenet
Lucene.Net4.8 PanGu分词 https://github.com/LonghronShen/Lucene.Net.Analysis.PanGu
但是只有code版的,没有.net 4.5版的,所以暂时没有做分词,后期再做。已经有原来支持Lucene.Net 3.03的版本和code版,应该可以根据这些做出适用的分词的。
测试使用数据(搜狗实验室下载的):http://www.sogou.com/labs/resource/list_news.php
用Lucene.Net 4.8(Part 1) - 基本实现搜索:http://programagic.ca/blog/search-with-lucenenet-part-1-basic-implementation
一个人的学习笔记,不过是英文的,随便翻译下就能看,我有很多是看这个写的。
另一个人学习笔记:http://www.cnblogs.com/dacc123/p/8035438.html
这个是我在国内找到的第一个Lucene.Net 4.8的介绍了,有深度,适合有一定的基础的人看。
Lucene.Net4.8 的一个预发布视频 :https://channel9.msdn.com/Blogs/MVP-VisualStudio-Dev/LuceneNET-48-a-pre-release-introduction
这个是16年底发布的,英语好的可以看看,不过也有中文字幕。