本章阅读概要

1、Lucenne.Net简介

2、介绍盘古分词器

3、Lucene.Net实例分析

4、结束语(Demo下载)

Lucene.Net简介

  Lucene.net是Lucene的.net移植版本,是一个开源的全文检索引擎开发包,即它不是一个完整的全文检索引擎,而是一个全文检索引擎的架构,提供了完整的查询引擎和索引引擎。开发人员可以基于Lucene.net实现全文检索的功能。   

  Lucene.net是Apache软件基金会赞助的开源项目,基于Apache License协议。   

  Lucene.net并不是一个爬行搜索引擎,也不会自动地索引内容。我们得先将要索引的文档中的文本抽取出来,然后再将其加到Lucene.net索引中。标准的步骤是先初始化一个Analyzer、打开一个IndexWriter、然后再将文档一个接一个地加进去。一旦完成这些步骤,索引就可以在关闭前得到优化,同时所做的改变也会生效。这个过程可能比开发者习惯的方式更加手工化一些,但却在数据的索引上给予你更多的灵活性。

(来自百度百科)

盘古分词器

盘古分词是一个中英文分词组件。作者eaglet 曾经开发过KTDictSeg 中文分词组件,拥有大量用户。作者基于之前分词组件的开发经验,结合最新的开发技术重新编写了盘古分词组件。主要有以下功能:

1、中文未登陆词识别

2、词频优先

3、一元分词,多元分词

4、中文人名分词

5、繁体中文分词

6、英文分词

7、用户自定义规则(字典管理,动态加载字典,关键词高亮)

……

由于盘古分词器不是本章的重点内容,就简单带过了。有兴趣的朋友可以自己网上找找相关资料。文章末尾会提供一个盘古分词器的应用程序供下载

Lucene.Net实例分析

先上一下Demo的图把,看下最后运行效果:

数据是临时随便创建的数据,表格和样式也是随便画的,不喜欢的朋友多包涵呐!

接下来就一步一步来讲解整个编码过程(主要对一些核心的类和细节作为讲解过程),Let's GO

第一步:创建索引

1、由于索引是存放在硬盘里的,所以先定义一个索引的目录

 1         /// <summary>2         /// 索引存放目录3         /// </summary>4         protected string IndexDic5         {6             get7             {8                 return Server.MapPath("/IndexDic");9             }
10         }

2、创建索引器把要索引的内容写入到指定目录

1

IndexWriter writer = new IndexWriter(IndexDic, PanGuAnalyzer, isCreate, Lucene.Net.Index.IndexWriter.MaxFieldLength.LIMITED);

索引器的构造函数参数说明:

IndexDic是索引存放目录

PanGuAnalyzer是盘古解析器(由于默认的解析器解析能力不强,所以替换为这个)

IsCreate是索引创建方式(true:重新新建索引,false:从旧的索引执行追加)

Lucene.Net.Index.IndexWriter.MaxFieldLength.LIMITED是文件长度是否限制

3、创建索引Document和往文档写入索引内容

 1         private void AddIndex(IndexWriter writer, string title, string content,string date)2         {3             try4             {5                 Document doc = new Document();6                 doc.Add(new Field("Title", title, Field.Store.YES, Field.Index.ANALYZED));//存储且索引7                 doc.Add(new Field("Content", content, Field.Store.YES, Field.Index.ANALYZED));//存储且索引8                 doc.Add(new Field("AddTime", date, Field.Store.YES, Field.Index.NOT_ANALYZED));//存储且索引9                 writer.AddDocument(doc);
10             }
11             catch (FileNotFoundException fnfe)
12             {
13                 throw fnfe;
14             }
15             catch (Exception ex)
16             {
17                 throw ex;
18             }
19         }

Document是索引文档,可以理解成数据库里的记录

Field是索引文档里的字段,可以直接理解成数据库里的字段

Field构造函数说明:

第一个是字段名称(实例里是Title,Content,AddTime)。

第二个是字段的存储方式(Field.Store.YES:进行存储,Filed.Store.No:不进行存储)有些字段值比较大,可以选择No不存储,对字段进行存储是为了检索的时候对某些字段进行提取。

第三个是是否索引(Field.Index.ANALYZED:索引, Field.Index.NOT_ANALYZED:非索引)

4、到此为止索引就创建完成了,应该可以看到索引目录会产生几个文件,如下图:

第二步:搜索索引

lucene的搜索相当强大,它提供了很多辅助查询类,每个类都继承自Query类,各自完成一种特殊的查询,你可以像搭积木一样将它们任意组合使用,完成一些复杂操 作;另外lucene还提供了Sort类对结果进行排序,提供了Filter类对查询条件进行限制。你或许会不自觉地拿它跟SQL语句进行比 较:“lucene能执行and、or、order by、where、like ‘%xx%’操作吗?”回答是:“当然没问题!”

 1         private void SearchIndex()2         {3             Dictionary<string, string> dic = new Dictionary<string, string>();4             BooleanQuery bQuery = new BooleanQuery();5             string title = string.Empty;6             string content = string.Empty;7             if (Request.Form["title"] != null && Request.Form["title"].ToString()!="")8             {9                 title =GetKeyWordsSplitBySpace( Request.Form["title"].ToString());
10                 QueryParser parse = new QueryParser("Title", PanGuAnalyzer);
11                 Query query = parse.Parse(title);
12                 parse.SetDefaultOperator(QueryParser.Operator.AND);
13                 bQuery.Add(query, BooleanClause.Occur.MUST);
14                 dic.Add("title",Request.Form["title"].ToString());
15                 txtTitle = Request.Form["title"].ToString();
16             }
17             if (Request.Form["content"] != null && Request.Form["content"].ToString() != "")
18             {
19                 content = GetKeyWordsSplitBySpace(Request.Form["content"].ToString());
20                 QueryParser parse = new QueryParser("Content", PanGuAnalyzer);
21                 Query query = parse.Parse(content);
22                 parse.SetDefaultOperator(QueryParser.Operator.AND);
23                 bQuery.Add(query, BooleanClause.Occur.MUST);
24                 dic.Add("content",Request.Form["content"].ToString());
25                 txtContent = Request.Form["content"].ToString();
26             }
27             if (bQuery != null && bQuery.GetClauses().Length>0)
28             {
29                 GetSearchResult(bQuery, dic);
30             }
31         }

这段代码创建了一个索引查询器,对title和content这两个字段进行查询。

1、介绍各种Query

TermQuery: 首先介绍最基本的查询,如果你想执行一个这样的查询:在content字段中查询包含‘刘备的document”,那么你可以用TermQuery:

1             Term t = new Term("content", "刘备");
2             Query query = new TermQuery(t);

BooleanQuery :如果你想这么查询:在content字段中包含”刘备“并且在title字段包含”三国“的document”,那么你可以建立两个TermQuery并把它们用BooleanQuery连接起来:

1             TermQuery termQuery1 = new TermQuery(new Term("content", "刘备"));
2             TermQuery termQuery2 = new TermQuery(new Term("title", "三国"));
3             BooleanQuery booleanQuery = new BooleanQuery();
4             booleanQuery.Add(termQuery1, BooleanClause.Occur.SHOULD);
5             booleanQuery.Add(termQuery2, BooleanClause.Occur.SHOULD);

WildcardQuery :如果你想对某单词进行通配符查询,你可以用WildcardQuery,通配符包括’?’匹配一个任意字符和’*’匹配零个或多个任意字符,例如你搜索’三国*’,你可能找到’三国演义’或者’三国志’:

1             Query query = new WildcardQuery(new Term("content", "三国*"));

PhraseQuery :你可能对中日关系比较感兴趣,想查找‘中’和‘日’挨得比较近(5个字的距离内)的文章,超过这个距离的不予考虑,你可以:

1             PhraseQuery query = new PhraseQuery();
2             query.SetSlop(5);
3             query.Add(new Term("content ", "中"));
4             query.Add(new Term("content", "日"));

那么它可能搜到“中日合作……”、“中方和日方……”,但是搜不到“中国某高层领导说日本欠扁”。

PrefixQuery :如果你想搜以‘中’开头的词语,你可以用PrefixQuery:

1             PrefixQuery query = new PrefixQuery(new Term("content ", "中"));

FuzzyQuery :FuzzyQuery用来搜索相似的term,使用Levenshtein算法。假设你想搜索跟‘wuzza’相似的词语,你可以:

1             Query query = new FuzzyQuery(new Term("content", "wuzza"));

你可能得到‘fuzzy’和‘wuzzy’。

RangeQuery: 另一个常用的Query是RangeQuery,你也许想搜索时间域从20060101到20060130之间的document,你可以用RangeQuery:

1             RangeQuery query = new RangeQuery(new Term("time","20060101"), new Term("time","20060130"), true);

最后的true表示用闭合区间。

第三步:返回索引结果

上面介绍完各种查询的Query,接下来看看LuceneNet返回的数据集如何处理,如何显示高亮,上代码:

 1 private void GetSearchResult(BooleanQuery bQuery,Dictionary<string,string> dicKeywords)2         {          3             IndexSearcher search = new IndexSearcher(IndexDic,true);4             Stopwatch stopwatch = Stopwatch.StartNew();5             //SortField构造函数第三个字段true为降序,false为升序6             Sort sort = new Sort(new SortField("AddTime", SortField.DOC, true));7             TopDocs docs = search.Search(bQuery, (Filter)null, PageSize * PageIndex, sort);8             stopwatch.Stop();9             if (docs != null && docs.totalHits > 0)
10             {
11                 lSearchTime = stopwatch.ElapsedMilliseconds;
12                 txtPageFoot = GetPageFoot(PageIndex, PageSize, docs.totalHits, "sabrosus");
13                 for (int i = 0; i < docs.totalHits; i++)
14                 {
15                     if (i >= (PageIndex - 1) * PageSize && i < PageIndex * PageSize)
16                     {
17                         Document doc = search.Doc(docs.scoreDocs[i].doc);
18                         Article model = new Article()
19                         {
20                             Title = doc.Get("Title").ToString(),
21                             Content = doc.Get("Content").ToString(),
22                             AddTime = doc.Get("AddTime").ToString()
23                         };
24                         list.Add(SetHighlighter(dicKeywords, model));
25                     }
26                 }
27             }
28         }

最后这段代码相对比较简单,我就说下几个关键的类和高亮提示把。

1、关键类说明:

IndexSearcher:索引查询器,它的构造函数有两个参数,一个是索引文件路径,一个是是否只读(一般都设置为true就可以)。这个东西可以理解为SqlServer里面的查询分析器。

Sort:看字眼可知道是索引排序类。主要说一下第三个参数,第三个参数是排序方式(true为降序,false为升序)。

TopDocs:这个是查询后返回的文档,可以理解为Sqlserver的表,search.Search可以当做是在查询分析器里按了一次F5查询。

2、设置关键字高亮:

 1         private Article SetHighlighter(Dictionary<string, string> dicKeywords, Article model)2         {3             SimpleHTMLFormatter simpleHTMLFormatter = new PanGu.HighLight.SimpleHTMLFormatter("<font color=\"green\">", "</font>");4             Highlighter highlighter = new PanGu.HighLight.Highlighter(simpleHTMLFormatter, new Segment());5             highlighter.FragmentSize = 50;6             string strTitle = string.Empty;7             string strContent = string.Empty;8             dicKeywords.TryGetValue("title", out strTitle);9             dicKeywords.TryGetValue("content", out strContent);
10             if (!string.IsNullOrEmpty(strTitle))
11             {
12                 model.Title = highlighter.GetBestFragment(strTitle, model.Title);
13             }
14             if (!string.IsNullOrEmpty(strContent))
15             {
16                 model.Content = highlighter.GetBestFragment(strContent, model.Content);
17             }
18             return model;
19         }

这里用的也是盘古的高亮组件,设置高亮主要分两个步骤:

设置高亮的显示样式、设置高亮的查询关键字

SimpleHTMLFormatter:这个类是一个HTML的格式类,构造函数有两个,一个是开始标签,一个是结束标签。

Segment:添加索引时并不是每个document都马上添加到同一个索引文件,它们首先被写入到不同的小文件,然后再合并成一个大索引文件,这里每个小文件都是一个segment。

结束语

感谢大家的阅读,如果这篇文章能帮的上你,那是我的荣幸。如果文章哪里写的不好,还请多多指教。

点击下载demo

Lucene.Net+盘古分词器(详细介绍)相关推荐

  1. Lucene.Net+盘古分词器(详细介绍)(转)

    Lucene.Net+盘古分词器(详细介绍)(转) Lucene.Net+盘古分词器(详细介绍) 本章阅读概要 1.Lucenne.Net简介 2.介绍盘古分词器 3.Lucene.Net实例分析 4 ...

  2. Lucene.Net3.0.3+盘古分词器学习使用

    一.Lucene.Net介绍 Lucene.net是Lucene的.net移植版本,是一个开源的全文检索引擎开发包,即它不是一个完整的全文检索引擎,而是一个全文检索引擎的架构,提供了完整的查询引擎和索 ...

  3. [Linux]Linux下安装和配置solr/tomcat/IK分词器 详细实例二.

    为了更好的排版, 所以将IK分词器的安装重启了一篇博文,  大家可以接上solr的安装一同查看. [Linux]Linux下安装和配置solr/tomcat/IK分词器 详细实例一: http://w ...

  4. Linux下安装和配置solr/tomcat/IK分词器 详细实例二.

    为了更好的排版, 所以将IK分词器的安装重启了一篇博文,  大家可以接上solr的安装一同查看. [Linux]Linux下安装和配置solr/tomcat/IK分词器 详细实例一: http://w ...

  5. 如何在基于Lucene的中文分词器中添加自定义词典(如Paoding、mmseg4j、IK Analyzer)...

    如何在基于Lucene的中文分词器中添加自定义词典(如Paoding.mmseg4j.IK Analyzer) 2013-07-08 21:54:29|  分类: 计算机 |字号 订阅 1. 使用Pa ...

  6. lucene构建同义词分词器

    lucene4.0版本号以后 已经用TokenStreamComponents 代替了TokenStream流.里面包含了filter和tokenizer 在较复杂的lucene搜索业务场景下,直接网 ...

  7. Linux下安装和配置solr/tomcat/IK分词器 详细实例一.

    在这里一下讲解着三个的安装和配置, 是因为solr需要使用tomcat和IK分词器, 这里会通过图文教程的形式来详解它们的安装和使用. 注: 本文属于原创文章, 如若转载,请注明出处, 谢谢. 关于设 ...

  8. Lucene.Net+盘古分词-开发自己的搜索引擎

    //封装类 using System; using System.Collections.Generic; using System.Linq; using System.Web; using Luc ...

  9. org.wltea.analyzer.lucene.IKAnalyzer(IK分词器)

    问题原因 : solr自带的jetty启动缺少IK分词器的jar包 解决方法 : 去下载一个 ik-analyzer-solr5-5.x.jar,放在/home/solr-7.7.3/server/s ...

  10. Lucene初学——3. 分词器学习

    1.demo public class AnalyzerStudy {private static String str = "分词器测试 Lucene 案例 开发 by future fo ...

最新文章

  1. 最短路算法总结(入门版)
  2. 430. 扁平化多级双向链表
  3. Edge使用手机版切换到电脑模式的方法
  4. Linux内核:进程上下文切换
  5. osg 镜面_浙江天梭手表镜面抛光
  6. 赠书 | 原动力——改变未来世界的5大核心力量
  7. 概率图模型(PGM):贝叶斯网(Bayesian network)初探
  8. ld链接动态库静态库问题
  9. BUCK电感工作模式
  10. python滚动广告牌,Discovery Live 参数化建模案例-设计广告牌风场选址
  11. 怎么把mov转换为mp4?
  12. Apache Velocity 模板语言 特殊字符${ $!{ 原样输出问题 转义符 # ! 无效
  13. bat 切换网络适配器_Windows批处理自动切换IP地址设置无线网络和以太网的IP地址...
  14. linux终端界面美化,Ubuntu 18.04系统美化记录:Grub2\主题\登录界面\终端美化
  15. halcon C++编程 第22讲 图像镜像 tcy
  16. 记一次rc.local中python脚本无法运行的解决过程
  17. 7月16日周二晚上,陈勇,【敏捷网络课堂第六期】【免费】敏捷开发早期估算...
  18. .net源码分析 – DictionaryTKey, TValue
  19. virtualenv简单使用
  20. 【转载】通过 FUNCTION NET_DUE_DATE_GET 得到MIRO付款日期(DUE ON DATE)

热门文章

  1. 操作系统名词中英文对照(一)
  2. linux mysql 挂马_解决数据库被挂马最快方法
  3. web前端-写给大家看的设计书-笔记-颜色运用-色轮使用
  4. 伽罗华有限域_伽罗华域(Galois Field,GF,有限域)乘法运算 | 学步园
  5. 电脑总是意外从睡眠状态唤醒,可以找出原因然后解决
  6. VC静态库开发与使用
  7. AutoCAD2006启动慢解决方案
  8. 时空本质性差异:两点间的距离不再是直线最短
  9. mysql插入微信名称中的特殊字符
  10. 计算机无法验证签名,计算机中win10/win7无法验证文件数字签名的解决方法