Net简单介绍和分词,盘古真人分词

正文参考自:

本文首要回顾介绍怎么样利用eaglet的天神分词在lucene.net中进行创办索引和归纳寻找。盘古真人分词是eaglet大大的杰作,如若您还未有品味使用过,希望本文的介绍会对你有所支持。

本文重要回顾介绍如何运用eaglet的天神分词在lucene.net中开始展览创办索引和精炼找寻。盘古真人分词是eaglet大大的杰作,要是您还向来不品味选用过,希望本文的介绍会对您具备协助。

目录

      

一、盘古真人分词参考资料汇总

牛人的进献不仅仅是无私提供几个工具,几个类库,多少个开源项目,还有他们的宏达,对学识精晓的深浅,以及谦虚低调的神态。大拿的人格吸动力往往都是很吸引人的。向eaglet致敬。

 

一、盘古真人分词参考资料汇总

牛人的贡献不仅仅是无私提供多少个工具,多少个类库,多少个开源项目,还有他们的博雅,对学识精通的深度,以及谦虚低调的情态。大拿的人格魅力往往都以很迷惑人的。向eaglet致敬。

 

Lucene.net站内寻觅—一、SEO优化
Lucene.net站内搜索—2、Lucene.Net简要介绍和分词
Lucene.net站内搜索—叁、最轻巧易行搜索引擎代码
Lucene.net站内搜索—4、寻找引擎第1版技能储备(简要介绍Log四Net、生产者消费者格局)
Net简单介绍和分词,盘古真人分词。Lucene.net站内寻找—伍、找寻引擎第二版达成
Lucene.net站内搜索—陆、站内搜索第二版

正文全数需求选拔的文书下载包括项目:

二、使用盘古真人分词器(PanGuAnalyzer)打算专门的学问

(1)、PanGu.xml文件

其一文件根本保存盘古分词的常用配置,当中DictionaryPath
指明字典所在目录,可感觉相对路线也得以为相对路线;MatchOptions 对应分词选项;Parameters
对于分词参数。本文示例demo中,作者选取的是暗中认可配置。同时在该xml文件的习性上,把它的变动操作设置成“嵌入的能源”。

(2)、如您所知,分词词库的保险也是上天分词的一大首要专门的学问。本文QueryApp调节台应用程序的bin目录下的Dictionaries是从codeplex上下载下来的(默许放在应用程序bin目录下)。那和(一)中的PanGu.xml的DictionaryPath 配置节点有关。

(三)、应用程序中(本文即QueryApp调节台应用程序)必须同时引述Lucene.Net.dll,PanGu.dll和PanGu.Lucene.Analyzer.dll。

 

二、使用盘古真人分词器(PanGuAnalyzer)希图干活

(1)、PanGu.xml文件

那几个文件根本保存盘古真人分词的常用配置,在那之中DictionaryPath
指明字典所在目录,可以为相对路径也得认为相对路线;MatchOptions 对应分词选项;Parameters
对于分词参数。本文示例demo中,作者选用的是私下认可配置。同时在该xml文件的习性上,把它的变化操作设置成“嵌入的财富”。

(二)、如您所知,分词词库的敬服也是上天分词的一大首要工作。本文QueryApp调节台应用程序的bin目录下的Dictionaries是从codeplex上下载下来的(默许放在应用程序bin目录下)。那和(1)中的PanGu.xml的DictionaryPath 配置节点有关。

(三)、应用程序中(本文即QueryApp调节台应用程序)必须同时引述Lucene.Net.dll,PanGu.dll和PanGu.Lucene.Analyzer.dll。

 

Lucene.Net简介

   
Lucene.Net是由Java版本的Lucene(卢思银)移植过来的,全体的类、方法都大约和Lucene1模同样,因而利用时参考
Lucene 就能够。

   
Lucene.Net只是一个全文字笔迹核查索开采包(就好像ADO.Net和管制类别的涉嫌),不是3个成型的寻觅引擎,它的效用就是:把多少扔给
Lucene.Net ,查询数据的时候从Lucene.Net
查询数据,能够视作是提供了全文字笔迹查证索功用的2个数据库。SQLServer春季Lucene.Net各存1份,目的差别样。Lucene.Net不管文本
数据怎么来的。用户可以基于Lucene.Net开辟满意自个儿必要的搜求引擎。

   
Lucene.Net只可以对文件消息进行检索。如若不是文件音讯,要退换为文本信息,比如要检索Excel文件,就要用NPOI把Excel读取成字符
串,然后把字符串扔给Lucene.Net。Lucene.Net会把扔给它的文书切词保存,加速检索速度。midomi.com。因为是保留的时候分词
(切词),所以搜索速度尤其快!索引库暗中同意保存的是“词的目录”

要神速的从《红楼》中搜索词,能够先遍历那本书建2个词和页数的应和目录。第2遍“找词”相当慢,不过寻找就快了。

美高梅开户网址 1

 Lucene配置文件下载

三、创制索引

Lucene.Net的IndexWriter在实例化的时候,要求3个Analyzer实例,使用盘古真人分词进行索引成立比非常粗略,只要将PanGuAnalyzer实例传入IndexWriter构造函数,按步就班构造索引就可以:

view
sourceprint?

01 public static void PrepareIndex(bool isPangu)
02 {
03     Analyzer analyzer = null;
04     if (isPangu)
05     {
06         analyzer = new PanGuAnalyzer();//盘古Analyzer
07     }
08     else
09     {
10         analyzer = new StandardAnalyzer(Version.LUCENE_29);
11     }
12     DirectoryInfo dirInfo = Directory.CreateDirectory(Config.INDEX_STORE_PATH);
13     LuceneIO.Directory directory = LuceneIO.FSDirectory.Open(dirInfo);
14     IndexWriter writer = new IndexWriter(directory, analyzer, true, IndexWriter.MaxFieldLength.LIMITED);
15     CreateIndex(writer, "jeffreyzhao", "博客园有一个老赵,人格魅力巨大,洋名就叫jeffreyzhao。据我所知,他还是一个胖子,一个钢琴业余爱好者。");
16     CreateIndex(writer, "lucene测试", "这是一个测试,关于lucene.net的 关注老赵");
17     CreateIndex(writer, "博客园里有牛人", "Hello World. 我认识的一个高手,他拥有广博的知识,有极客的态度,还经常到园子里来看看");
18     CreateIndex(writer, "奥巴马", "美国现任总统是奥巴马?确定不是奥巴牛和奥巴羊 不知道问老赵");
19     CreateIndex(writer, "奥林匹克", "奥林匹克运动会将来到南美美丽热情的国度巴西,也就是亚马逊河流域的一个地方");
20     CreateIndex(writer, "写给自己", "博客园的jeffwong,新的开始,继续努力了");
21     writer.Optimize();
22     writer.Close();
23 }

 

三、创立索引

Lucene.Net的IndexWriter在实例化的时候,需求2个Analyzer实例,使用盘古真人分词实行索引创造很简单,只要将PanGuAnalyzer实例传入IndexWriter构造函数,按步就班构造索引就可以:

view
sourceprint?

01 public static void PrepareIndex(bool isPangu)
02 {
03     Analyzer analyzer = null;
04     if (isPangu)
05     {
06         analyzer = new PanGuAnalyzer();//盘古Analyzer
07     }
08     else
09     {
10         analyzer = new StandardAnalyzer(Version.LUCENE_29);
11     }
12     DirectoryInfo dirInfo = Directory.CreateDirectory(Config.INDEX_STORE_PATH);
13     LuceneIO.Directory directory = LuceneIO.FSDirectory.Open(dirInfo);
14     IndexWriter writer = new IndexWriter(directory, analyzer, true, IndexWriter.MaxFieldLength.LIMITED);
15     CreateIndex(writer, "jeffreyzhao", "博客园有一个老赵,人格魅力巨大,洋名就叫jeffreyzhao。据我所知,他还是一个胖子,一个钢琴业余爱好者。");
16     CreateIndex(writer, "lucene测试", "这是一个测试,关于lucene.net的 关注老赵");
17     CreateIndex(writer, "博客园里有牛人", "Hello World. 我认识的一个高手,他拥有广博的知识,有极客的态度,还经常到园子里来看看");
18     CreateIndex(writer, "奥巴马", "美国现任总统是奥巴马?确定不是奥巴牛和奥巴羊 不知道问老赵");
19     CreateIndex(writer, "奥林匹克", "奥林匹克运动会将来到南美美丽热情的国度巴西,也就是亚马逊河流域的一个地方");
20     CreateIndex(writer, "写给自己", "博客园的jeffwong,新的开始,继续努力了");
21     writer.Optimize();
22     writer.Close();
23 }

 

分词

   
分词是主导的算法,寻觅引擎内部保存的正是几个个的“词(Word)”。英文分词很简短,根据空格分隔就足以。中文则麻烦,把“新加坡,Hi应接你们我们”
拆成“东京 Hi 接待 你们我们”。

“the”,“,”,“和”,“啊”,“的”等对于搜索来讲无意义的词一般都属于不插足分词的画饼充饥单词(noise
word)。

   
Lucene.Net中区别的分词算法便是见仁见智的类。全数分词算法类都从Analyzer类传承,区别的分词算法有两样的优缺点。

(*)内置的StandardAnalyzer是将英文根据空格、标点符号等张开分词,将普通话根据单个字张开分词,2个汉字算贰个词。代码见备注

(*)2元分词算法,每四个汉字算多少个单词,“迎接你们我们”会分词为“招待  
迎你  你们 们大 
大家”,网络找到的二个2元分词算法CJKAnalyzer。面试的时候能揭破不一样的分词算法的差异。

任凭一元分词依然二元分词,分词成效相比较高,不过分出无用词,因而索引库大。查询效用低。

遗闻词库的分词算法,基于一个词库进行分词,可以加强分词的成功率。有得心应手、盘古真人分词等。效能低。

一、
StandardAnalyzer示例(不用背代码,拷过来知道改哪个地方就可以,作者复制粘贴的代码你也如出一辙复制粘贴)

 Analyzer analyzer = new StandardAnalyzer();

           TokenStream tokenStream =
analyzer.TokenStream(“”,newStringReader(“小编是实在爱你”));

           Lucene.Net.Analysis.Token token = null;

           while ((token =tokenStream.Next()) != null)

           {

               Console.WriteLine(token.TermText());

           }

华语分词配置文件下载

四、简单找寻

搜寻同样也比较轻松上手,只要将QueryParser中的Analyzer参数使用PanGuAnalyzer实例就足以了:

view
sourceprint?

1 public static void PanguQueryTest(Analyzer analyzer, string field, string keyword)
2 {
3     QueryParser parser = new QueryParser(Version.LUCENE_29, field, analyzer);
4     string panguQueryword = GetKeyWordsSplitBySpace(keyword, new PanGuTokenizer());//对关键字进行分词处理
5     Query query = parser.Parse(panguQueryword);
6     ShowQueryExpression(analyzer, query, keyword);
7     SearchToShow(query);
8     Console.WriteLine();
9 }

里面对根本字伸开盘古真人分词处理的函数GetKeyWordsSplitBySpace直接来源于eaglet提供的示范代码:

view
sourceprint?

01 public static string GetKeyWordsSplitBySpace(string keywords, PanGuTokenizer ktTokenizer)
02 {
03     StringBuilder result = new StringBuilder();
04     ICollection<WordInfo> words = ktTokenizer.SegmentToWordInfos(keywords);
05     foreach (WordInfo word in words)
06     {
07         if (word == null)
08         {
09             continue;
10         }
11         result.AppendFormat("{0}^{1}.0 ", word.Word, (int)Math.Pow(3, word.Rank));
12     }
13     return result.ToString().Trim();
14 }

PanGuTokenizer的SegmentToWordInfos那个措施,作者正在查阅源码完毕,希望得以领会的更深透一些。

末段,本文面向的对象是初我们,即使您有好的使用经验和提出敬请不吝赐教。

 

demo下载:LuceneNetApp

四、轻巧搜索

探索同样也正如便于上手,只要将QueryParser中的Analyzer参数使用PanGuAnalyzer实例就足以了:

view
sourceprint?

1 public static void PanguQueryTest(Analyzer analyzer, string field, string keyword)
2 {
3     QueryParser parser = new QueryParser(Version.LUCENE_29, field, analyzer);
4     string panguQueryword = GetKeyWordsSplitBySpace(keyword, new PanGuTokenizer());//对关键字进行分词处理
5     Query query = parser.Parse(panguQueryword);
6     ShowQueryExpression(analyzer, query, keyword);
7     SearchToShow(query);
8     Console.WriteLine();
9 }

里面对首要字张开盘古分词管理的函数GetKeyWordsSplitBySpace直接来源于eaglet提供的言传身教代码:

view
sourceprint?

01 public static string GetKeyWordsSplitBySpace(string keywords, PanGuTokenizer ktTokenizer)
02 {
03     StringBuilder result = new StringBuilder();
04     ICollection<WordInfo> words = ktTokenizer.SegmentToWordInfos(keywords);
05     foreach (WordInfo word in words)
06     {
07         if (word == null)
08         {
09             continue;
10         }
11         result.AppendFormat("{0}^{1}.0 ", word.Word, (int)Math.Pow(3, word.Rank));
12     }
13     return result.ToString().Trim();
14 }

PanGuTokenizer的SegmentToWordInfos那个方法,笔者正在查看源码达成,希望能够精晓的更不亦乐乎一些。

说起底,本文面向的目的是初学者,若是您有好的利用经验和提议敬请不吝赐教。

 

demo下载:LuceneNetApp

天公分词算法使用

切实用法参考《PanguMannual.pdf》

打开PanGu4Lucene\WebDemo\Bin,增多对PanGu.dll(同目录下不要有Pangu.xml,那贰个默许的配置文件的精选对于分词结果有广大无用消息)、PanGu.Lucene.Analyzer.dll的引用

把上边代码的Analyzer用PanGuAnalyzer取代

运维开采提醒供给dct文件,因为不可能把词库写死在dll中,因而必要提供单身的词库文件,遵照报错放到合适的门径中。

通用技能:把Dict目录下的文本“复制到输出目录”设定为“即使较新则复制”,每便改变的时候都会活动把公文拷到bin\Debug
下,分外有利。(唯有Web应用程序有十一分选项,网址并未有。)恒久不要对bing\debug下的事物做直接的修改,要改“源文件”。

词库的编写,使用DictManage.exe,对单词编辑的时候要先物色。职业的项目中要将行当单词增多到词库中,比方餐饮搜索、租房找寻、录制查找等。

注:现身Dict路线的题目,没有找到配置文件,私下认可就是Dict目录,设定Pangu.xml的复制到输出设置为“借使较新则复制”就可以。也许词典目录就取名叫Dict,不要布署文件。

Demo:

一元分词

一、  新建项目——ASP.NET Web应用程序Search德姆o

二、  新建文件夹lib,存放dll文件Lucene.Net.dll

3、  添加Lucene.Net.dll引用

美高梅开户网址 2美高梅开户网址 3美高梅开户网址 4

二元分词

壹、拷贝多少个类到根目录下

美高梅开户网址 5美高梅开户网址 6

天公分词

壹、  拷贝八个dll PanGu.dll和PanGu.Lucene.Analyzer.dll到lib目录下

美高梅开户网址 7

美高梅开户网址,二、  加多那多个dll的引用

三、  增添Dict词库目录和词库文件

美高梅开户网址 8

四、  修改分词代码

五、  假使出现如下错误

美高梅开户网址 9

把Dict目录下的公文“复制到输出目录”设定为“假若较新则复制”

美高梅开户网址 10美高梅开户网址 11

分词代码如下:

aspx:

[html] view
plaincopy美高梅开户网址 12美高梅开户网址 13

  1.  <form id=”form1″ runat=”server”>  
  2.     <div>  
  3.         <asp:TextBox ID=”txtContent” runat=”server” Height=”62px” TextMode=”MultiLine”   
  4.             Width=”191px”></asp:TextBox>  
  5.         <asp:Button ID=”btnOnePartWord”  
  6.             runat=”server” Text=”1元分词” onclick=”btnOnePartWord_Click” />  
  7.         <asp:Button ID=”btnTwoPartWord” runat=”server” Text=”二元分词”   
  8.             onclick=”btnTwoPartWord_Click” />  
  9. <asp:Button ID=”btnPanGu” runat=”server” Text=”盘古真人分词” onclick=”btnPanGu_Click” />  
  10.             <asp:ListBox ID=”lstWord” runat=”server” Width=”112px”></asp:ListBox>  
  11.     </div>  
  12. </form>  

cs:

[csharp] view
plaincopy美高梅开户网址 14美高梅开户网址 15

  1. using Lucene.Net.Analysis;  
  2. using System.IO;  
  3. using Lucene.Net.Analysis.Standard;  
  4. using NSharp.SearchEngine.Lucene.Analysis.Cjk;  
  5. using Lucene.Net.Analysis.PanGu;  
  6.   
  7. namespace SearchDemo.Pages  
  8. {  
  9.     public partial class 分词算法 : System.Web.UI.Page  
  10.     {  
  11.         protected void Page_Load(object sender, EventArgs e)  
  12.         {  
  13.   
  14.         }  
  15.   
  16.         protected void btnOnePartWord_Click(object sender, EventArgs e)  
  17.         {  
  18.             Analyzer oneAnalyzer = new 斯坦dardAnalyzer(); //一元分词  
  19.             PartWordMethod(oneAnalyzer);  
  20.         }  
  21.   
  22.         private void PartWordMethod(Analyzer analyzer)  
  23.         {  
  24.             lstWord.Items.Clear();  
  25.             //Analyzer analyzer = new PanGuAnalyzer();  
  26.             TokenStream tokenStream = analyzer.TokenStream(“”, new StringReader(txtContent.Text));  
  27.             Lucene.Net.Analysis.Token token = null;  
  28.   
  29.             while ((token = tokenStream.Next()) != null)  
  30.             {  
  31.                 string word = token.TermText();  
  32.                 lstWord.Items.Add(word);  
  33.             }  
  34.         }  
  35.   
  36.         protected void btnTwoPartWord_Click(object sender, EventArgs e)  
  37.         {  
  38.             Analyzer oneAnalyzer = new CJKAnalyzer(); //2元分词  
  39.             PartWordMethod(oneAnalyzer);  
  40.         }  
  41.         protected void btnPanGu_Click(object sender, EventArgs e)  
  42.         {  
  43.             Analyzer oneAnalyzer = new PanGuAnalyzer(); //盘古真人分词  
  44.             PartWordMethod(oneAnalyzer);  
  45.         }  
  46.     }  

本文项目下载Zip 

1.一元分词  / 2.2元分词 / 三.盘古真人分词 /
四.普通话分词 / 伍.简易搜索

用vs20一伍创设Windows窗体应用程序,创造好项目时回忆将其脾性改为“调节台应用程序”,当然也能够是暗中认可的,只是那样便于些。如下图

美高梅开户网址 16

1.壹元分词法

 除此外,还需求引用’Lucene.Net.dll‘

美高梅开户网址 17美高梅开户网址 18

 1 /// <summary>
 2         /// 一元分词法
 3         /// </summary>
 4         /// <param name="sender"></param>
 5         /// <param name="e"></param>
 6         private void button1_Click(object sender, EventArgs e)
 7         {
 8             Analyzer analyzer = new StandardAnalyzer(); // 标准分词 → 一元分词  
 9             TokenStream tokenStream = analyzer.TokenStream("", new StringReader("喝奶只喝纯牛奶,这是不可能的——黑夜中的萤火虫"));
10             Token token = null;
11             while ((token = tokenStream.Next()) != null) // 只要还有词,就不返回null  
12             {
13                 string word = token.TermText(); // token.TermText() 取得当前分词  
14                 Console.Write(word + "   |  ");
15             }
16         }

1元分词法

 

二.二元分词法

在刚刚的底蕴上,再引用文件夹“Analyzers”中的多个.cs文件,如下图

美高梅开户网址 19

 

美高梅开户网址 20美高梅开户网址 21

 /// <summary>
        /// 二元分词
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button2_Click(object sender, EventArgs e)
        {
            Analyzer analyzer = new CJKAnalyzer(); // 标准分词 → 一元分词  
            TokenStream tokenStream = analyzer.TokenStream("", new StringReader("喝奶只喝纯牛奶,这是不可能的——黑夜中的萤火虫"));
            Token token = null;
            while ((token = tokenStream.Next()) != null) // 只要还有词,就不返回null  
            {
                string word = token.TermText(); // token.TermText() 取得当前分词  
                Console.Write(word + "   |  ");
            }
        }

2元分词法

 

叁.盘古分词法

再引用以下四个布局文件

 

美高梅开户网址 22

美高梅开户网址 23

美高梅开户网址 24美高梅开户网址 25

/// <summary>
        /// 盘古分词法
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button3_Click(object sender, EventArgs e)
        {
            Analyzer analyzer = new PanGuAnalyzer(); // 盘古分词
            TokenStream tokenStream = analyzer.TokenStream("", new StringReader("喝奶只喝纯牛奶,这是不可能的——黑夜中的萤火虫"));
            Token token = null;
            while ((token = tokenStream.Next()) != null) // 只要还有词,就不返回null  
            {
                string word = token.TermText(); // token.TermText() 取得当前分词  
                Console.Write(word + "   |  ");
            }
        }

天神分词法

 

 要是不去更改,盘古真人词包中并不分包所需词汇,以下是运营效果图

美高梅开户网址 26

 

 而用‘DictManage.exe‘来开荒项目中的Dict.dct文件,增添词汇,并加以保存。

美高梅开户网址 27

 

下图是修改后的运维作效果果:

 美高梅开户网址 28

四.汉语分词算法 

美高梅开户网址 29

 

美高梅开户网址 30美高梅开户网址 31

 1 private void button1_Click(object sender, EventArgs e)
 2         {
 3             StringBuilder sb = new StringBuilder();
 4             sb.Remove(0, sb.Length);
 5             string t1 = "";
 6             int i = 0;
 7             Analyzer analyzer = new Lucene.China.ChineseAnalyzer();
 8             StringReader sr = new StringReader(richTextBox1.Text);
 9             TokenStream stream = analyzer.TokenStream(null, sr);
10 
11             long begin = System.DateTime.Now.Ticks;
12             Token t = stream.Next();
13             while (t != null)
14             {
15                 t1 = t.ToString();   //显示格式: (关键词,0,2) ,需要处理
16                 t1 = t1.Replace("(", "");
17                 char[] separator = { ',' };
18                 t1 = t1.Split(separator)[0];
19 
20                 sb.Append(i + ":" + t1 + "\r\n");
21                 t = stream.Next();
22                 i++;
23             }
24             richTextBox2.Text = sb.ToString();
25             long end = System.DateTime.Now.Ticks; //100毫微秒
26             int time = (int)((end - begin) / 10000); //ms
27 
28 
29             richTextBox2.Text += "耗时" + (time) + "ms \r\n=================================\r\n";
30         }

中文分词测试后台代码

 

伍.回顾搜索

创建web窗体SearchWords.aspx,如下图

美高梅开户网址 32

 

 

美高梅开户网址 33美高梅开户网址 34

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="SearchWords.aspx.cs" Inherits="PanGu_Search.Views.SearchWords" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title>最简单的搜索引擎</title>  
    <script>
    $(document).keydown(function (event) {
    if (event.keyCode == 13) {
        $("#btnGetSearchResult").click();
    }
    });
    </script>
</head>  
<body>  
    <form id="mainForm" runat="server">  
        <div align="center">  
            <asp:Button ID="btnCreateIndex" runat="server" Text="Create Index" OnClick="btnCreateIndex_Click" />  
            <asp:Label ID="lblIndexStatus" runat="server" Visible="false" />  
            <hr />  
            <asp:TextBox ID="txtKeyWords" runat="server" Text="" Width="250"></asp:TextBox>  
            <asp:Button ID="btnGetSearchResult" runat="server" Text="Search" OnClick="btnGetSearchResult_Click" />  
            <hr />  
        </div>  
        <div>  
            <ul>  
                <asp:Repeater ID="rptSearchResult" runat="server">  
                    <ItemTemplate>  
                        <li>Id:<%#Eval("Id") %><br /><%#Eval("Msg") %></li>  
                    </ItemTemplate>  
                </asp:Repeater>  
            </ul>  
        </div>  
    </form>  
</body>  
</html>  

前台aspx设计

美高梅开户网址 35美高梅开户网址 36

  /// <summary>
        /// 创建索引方法
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void btnCreateIndex_Click(object sender, EventArgs e)
        {
            string indexPath = Context.Server.MapPath("~/Index"); // 索引文档保存位置  
            FSDirectory directory = FSDirectory.Open(new DirectoryInfo(indexPath), new NativeFSLockFactory());
            bool isUpdate = IndexReader.IndexExists(directory); //判断索引库是否存在  
            if (isUpdate)
            {
                //  如果索引目录被锁定(比如索引过程中程序异常退出),则首先解锁  
                //  Lucene.Net在写索引库之前会自动加锁,在close的时候会自动解锁  
                //  不能多线程执行,只能处理意外被永远锁定的情况  
                if (IndexWriter.IsLocked(directory))
                {
                    IndexWriter.Unlock(directory);  //unlock:强制解锁,待优化  
                }
            }
            //  创建向索引库写操作对象  IndexWriter(索引目录,指定使用盘古分词进行切词,最大写入长度限制)  
            //  补充:使用IndexWriter打开directory时会自动对索引库文件上锁  
            IndexWriter writer = new IndexWriter(directory, new PanGuAnalyzer(), !isUpdate,
                IndexWriter.MaxFieldLength.UNLIMITED);

            for (int i = 1; i < 3; i++)
            {
                string txt = File.ReadAllText(Context.Server.MapPath("~/Upload/Articles/") + i + ".txt");
                //  一条Document相当于一条记录  
                Document document = new Document();
                //  每个Document可以有自己的属性(字段),所有字段名都是自定义的,值都是string类型  
                //  Field.Store.YES不仅要对文章进行分词记录,也要保存原文,就不用去数据库里查一次了  
                document.Add(new Field("id", i.ToString(), Field.Store.YES, Field.Index.NOT_ANALYZED));
                //  需要进行全文检索的字段加 Field.Index. ANALYZED  
                //  Field.Index.ANALYZED:指定文章内容按照分词后结果保存,否则无法实现后续的模糊查询   
                //  WITH_POSITIONS_OFFSETS:指示不仅保存分割后的词,还保存词之间的距离  
                document.Add(new Field("msg", txt, Field.Store.YES, Field.Index.ANALYZED,
                    Field.TermVector.WITH_POSITIONS_OFFSETS));
                //  防止重复索引,如果不存在则删除0条  
                writer.DeleteDocuments(new Term("id", i.ToString()));// 防止已存在的数据 => delete from t where id=i  
                                                                     //  把文档写入索引库  
                writer.AddDocument(document);
                Console.WriteLine("索引{0}创建完毕", i.ToString());
            }

            writer.Close(); // Close后自动对索引库文件解锁  
            directory.Close();  //  不要忘了Close,否则索引结果搜不到  

            lblIndexStatus.Text = "索引文件创建成功!";
            lblIndexStatus.Visible = true;
            btnCreateIndex.Enabled = false;
        }

创制索引方法

美高梅开户网址 37美高梅开户网址 38

/// <summary>
        /// 搜索方法
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void btnGetSearchResult_Click(object sender, EventArgs e)
        {
            string keyword = txtKeyWords.Text;

            string indexPath = Context.Server.MapPath("~/Index"); // 索引文档保存位置  
            FSDirectory directory = FSDirectory.Open(new DirectoryInfo(indexPath), new NoLockFactory());
            IndexReader reader = IndexReader.Open(directory, true);
            IndexSearcher searcher = new IndexSearcher(reader);
            // 查询条件  
            PhraseQuery query = new PhraseQuery();
            // 等同于 where contains("msg",kw)  
            query.Add(new Term("msg", keyword));
            // 两个词的距离大于100(经验值)就不放入搜索结果,因为距离太远相关度就不高了  
            query.SetSlop(100);
            // TopScoreDocCollector:盛放查询结果的容器  
            TopScoreDocCollector collector = TopScoreDocCollector.create(1000, true);
            // 使用query这个查询条件进行搜索,搜索结果放入collector  
            searcher.Search(query, null, collector);
            // 从查询结果中取出第m条到第n条的数据  
            // collector.GetTotalHits()表示总的结果条数  
            ScoreDoc[] docs = collector.TopDocs(0, collector.GetTotalHits()).scoreDocs;
            // 遍历查询结果  
            IList<SearchResult> resultList = new List<SearchResult>();
            for (int i = 0; i < docs.Length; i++)
            {
                // 拿到文档的id,因为Document可能非常占内存(DataSet和DataReader的区别)  
                int docId = docs[i].doc;
                // 所以查询结果中只有id,具体内容需要二次查询  
                // 根据id查询内容:放进去的是Document,查出来的还是Document  
                Document doc = searcher.Doc(docId);
                SearchResult result = new SearchResult();
                result.Id = Convert.ToInt32(doc.Get("id"));
                result.Msg = HighlightHelper.HighLight(keyword, doc.Get("msg"));

                resultList.Add(result);
            }

            // 绑定到Repeater  
            rptSearchResult.DataSource = resultList;
            rptSearchResult.DataBind();
        }

探求方法

美高梅开户网址 39美高梅开户网址 40

 protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                // 检查是否已存在生成的索引文件
                CheckIndexData();
            }
        }

        /// <summary>
        /// 检查索引是否创建成功
        /// </summary>
        private void CheckIndexData()
        {
            string indexPath = Context.Server.MapPath("~/Index"); // 索引文档保存位置
            var files = System.IO.Directory.GetFiles(indexPath);
            if (files.Length > 0)
            {
                btnCreateIndex.Visible = false;
                lblIndexStatus.Text = "简单搜索";
                lblIndexStatus.Visible = true;
            }
        }

检查索引是不是存在方法

 

 运维效果如图:

 

美高梅开户网址 41

 

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图