using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using Lucene.Net.Analysis; using Lucene.Net.Analysis.PanGu; using Lucene.Net.Analysis.Standard; using Lucene.Net.Documents; using Lucene.Net.Index; using Lucene.Net.Search; using Lucene.Net.Store; using NSharp.SearchEngine.Lucene.Analysis.Cjk; using PanGu.Dict; namespace y_lucen.net { public partial class Form1 : Form { public Form1() { InitializeComponent(); } /// <summary> /// 一元分词 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void button1_Click(object sender, EventArgs e) { //分词算法的基类 Analyzer analyzer=new StandardAnalyzer();//指定一元分词算法 TokenStream tokenStream = analyzer.TokenStream("", new StringReader("北京,HI欢迎你们大家"));//读取 Lucene.Net.Analysis.Token token= null; while ((token=tokenStream.Next())!=null) { listBox1.Items.Add(token.TermText()); } } /// <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("北京,HI欢迎你们大家"));//读取 Lucene.Net.Analysis.Token token = null; while ((token = tokenStream.Next()) != null) { listBox1.Items.Add(token.TermText()); } } /// <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("北京,HI欢迎你们大家,公共场合,大师说发放时安防监控了房间爱都十分理解是浪费就爱上"));//读取 Lucene.Net.Analysis.Token token = null; while ((token = tokenStream.Next()) != null) { listBox1.Items.Add(token.TermText()); } //WordDictionary word=new WordDictionary(); //word.InsertWord(,); } private void button4_Click(object sender, EventArgs e) { //指定lucene.net要存储的目录 string indexPath = @"D:\lucenedir";//注意和磁盘上文件夹的大小写一致,否则会报错。将创建的分词内容放在该目录下。 //打开用来存储数据的目录 FSDirectory directory=FSDirectory.Open(new DirectoryInfo(indexPath));//指定索引文件(打开索引目录)FS值得是就是FileSystem //对目录中数据进行读取 bool isUpdate = IndexReader.IndexExists(directory);//indexReader:对索引进行读取的类,该语句的作用:判断索引库文件夹是否存在以及所以特征文件是否存在 if (isUpdate) { //同时只能有一段代码对索引库进行写操作。当使用IndexWriter打开directory时会自动对索引库文件上锁。 //如果索引目录被锁定(比如索引过程中程序异常退出),则首先解锁(提示一下:如果我现在正在写着已经加锁了,但是还没有写完,这时候又来一个请求,那么久不解锁呀?这个问题后面会解决) if (IndexWriter.IsLocked(directory)) { IndexWriter.Unlock(directory); } } //lucene.net文件,分词算法,数据库是否存在不存在就创建 IndexWriter writer=new IndexWriter(directory,new PanGuAnalyzer(),isUpdate,Lucene.Net.Index.IndexWriter.MaxFieldLength.UNLIMITED);//向索引库中写索引。这是在这里加锁 for (int i = 1; i < +10; i++) { string txt = File.ReadAllText(@"D:\abc\aa\测试文件\" + i + ".txt", System.Text.Encoding.Default);//注意这个地方的编码 Document document=new Document();//表示一篇文档 //Field.Sote.YES:表示是否存储原值。只有当Field.Stord.YES在后面才能用doc.Get("number")取出值来,Field.Index.NOT_ANALYZED:不进行分词保存. document.Add((new Field("number",i.ToString(),Field.Store.YES,Field.Index.NOT_ANALYZED))); //Field.Index.ANALYZED:进行分词保存:也就是要进行全文的字段要设置分词保存(因为要进行模糊查询) //Lucene.Net.Documents.Field.TermVector.WITH_POSTITIONS_OFFSETS:不仅保存分词还保存分词的距离。 document.Add(new Field("body",txt,Field.Store.YES,Field.Index.ANALYZED,Lucene.Net.Documents.Field.TermVector.WITH_POSITIONS_OFFSETS)); writer.AddDocument(document); } writer.Close();//会自动解锁 directory.Close();//不要忘记Close,否则索引结果搜不到 } private void button5_Click(object sender, EventArgs e) { string indexPath = @"D:\lucenedir"; string kw = "面向对象";//搜索的关键词 //打开文件 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 kw.Split(‘ ‘))//先用空格,让用户去分词,空格分隔的就是词“计算机 专业” //{ // query.Add(new Term("body",word)); //} //query.Add(new Term("body","语言"));//可以添加查询条件,两则是add关系,顺序没有关系 //query.Add((new Term("body","大学生"))); query.Add(new Term("body",kw));//body中含有kw的文章 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(结束)的文档内容 //可以用来实现分页功能 this.listBox1.Items.Clear(); for (int i = 0; i < docs.Length; i++) { int docId = docs[i].doc;//得到查询结果文档的id(Lucene内部分配的id) Document doc = searcher.Doc(docId); this.listBox1.Items.Add(doc.Get("number") + "\r\n"); this.listBox1.Items.Add(doc.Get("body") + "\r\n"); this.listBox1.Items.Add("-------------\r\n"); } } } }
时间: 2024-11-16 15:45:29