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");
}
}
}
}