知识点
相关文章
更多最近更新
更多【转载】Lucence.Net
2019-03-27 01:03|来源: 网路
一、简介
Lucence.Net提供一组API,让我们能快速开发自己的搜索引擎,既全文搜索。
Lucene.Net是Apache基金会的开源项目。
dotNet版的可以在这里找到:http://incubator.apache.org/lucene.net/
最新源码可以直接使用SVN下载:https://svn.apache.org/repos/asf/lucene/lucene.net/tags/
源码网址有时会改变,具体下载不了时,可以到http://incubator.apache.org/lucene.net/查看。
二、简单示例
在下载到Lucence.Net源代码或是dll后,引入到我们的项目中。我们来作一个简单的实例
1。第一步:建立索引
- using Lucene.Net.Index;
- using Lucene.Net.Store;
- using Lucene.Net.Analysis;
- using Lucene.Net.Analysis.Standard;
- using Lucene.Net.Documents;
- /// <summary>
- /// 创建索引
- /// </summary>
- protected void CreatedIndex()
- {
- Analyzer analyzer = new StandardAnalyzer();
- IndexWriter writer = new IndexWriter("IndexDirectory", analyzer, true);
- AddDocument(writer, "SQL Server 2008 的发布", "SQL Server 2008 的新特性");
- AddDocument(writer, "ASP.Net MVC框架配置与分析", "而今,微软推出了新的MVC开发框架,也就是Microsoft ASP.NET 3.5 Extensions");
- writer.Optimize();
- writer.Close();
- }
- /// <summary>
- /// 建立索引字段
- /// </summary>
- /// <param name="writer"></param>
- /// <param name="title"></param>
- /// <param name="content"></param>
- protected void AddDocument(IndexWriter writer, string title, string content)
- {
- Document document = new Document();
- document.Add(new Field("title", title, Field.Store.YES, Field.Index.ANALYZED));
- document.Add(new Field("content", content, Field.Store.YES, Field.Index.ANALYZED));
- writer.AddDocument(document);
- }
第二步:使用索引(测试搜索)
- using Lucene.Net.Index;
- using Lucene.Net.Store;
- using Lucene.Net.Analysis;
- using Lucene.Net.Analysis.Standard;
- using Lucene.Net.Documents;
- using Lucene.Net.Search;
- using Lucene.Net.QueryParsers;
- /// <summary>
- /// 全文搜索
- /// </summary>
- /// <param name="title">搜索字段(范围)</param>
- /// <param name="content">搜索字段(范围)</param>
- /// <param name="keywords">要搜索的关键词</param>
- protected void Search(string title, string content, string keywords)
- {
- Analyzer analyzer = new StandardAnalyzer(); //分词器
- IndexSearcher searcher = new IndexSearcher("IndexDirectory"); //指定其搜索的目录
- MultiFieldQueryParser parser = new MultiFieldQueryParser(new string[] { title, content }, analyzer); //多字段搜索
- //QueryParser q = new QueryParser("indexcontent", new StandardAnalyzer()); //单字段搜索
- Query query = parser.Parse(keywords); //
- Hits hits = searcher.Search(query);
- for (int i = 0; i < hits.Length(); i++)
- {
- Document doc = hits.Doc(i);
- Response.Write(string.Format("字段{3}搜索到:{0} 字段{4}搜索到:{1}", doc.Get("title"), doc.Get("content"), title, content));
- }
- searcher.Close();
- }
Lucene.NET
----------------------------------------------------------------------
介绍一下Lucene.net的使用,使用了Lucene.Net.dll2.1 Highlighter.Net.dll 2.0(高亮) Lucene.Net.Analysis.Cn.dll 1.3(划词引擎):
1 添加索引

/// <summary>
/// 添加索引
/// </summary>
/// <param name="file">索引实体Files</param>
public void AddIndex(Files file) {
IndexWriter writer;
if (IndexReader.IndexExists(GetIndexPath)) {
//非第一次递加
writer = new IndexWriter(GetIndexPath, this.Analyzer, false);
}
else {
//第一次创建
writer = new IndexWriter(GetIndexPath, this.Analyzer, true);
}
Document doc = new Document();
doc.Add(new Field("FileId", file.ID, Field.Store.YES, Field.Index.UN_TOKENIZED));//Field.Index.UN_TOKENIZED 类似把这字段作为主键
doc.Add(new Field("Title", file.Title, Field.Store.YES, Field.Index.TOKENIZED));
switch (file.FileType) {
case FileType.Txt:
doc.Add(new Field("File", new StreamReader(file.Stream, System.Text.Encoding.Default)));
break;
case FileType.Word:
doc.Add(new Field("File", Doc2Text(file.FileName), Field.Store.YES, Field.Index.TOKENIZED));
break;
case FileType.Excel:
doc.Add(new Field("File", Xls2Text(file.FileName), Field.Store.YES, Field.Index.TOKENIZED));
break;
case FileType.Ppt:
doc.Add(new Field("File", Ppt2Text(file.FileName), Field.Store.YES, Field.Index.TOKENIZED));
break;
case FileType.Mht:
doc.Add(new Field("File", Doc2Text(file.FileName), Field.Store.YES, Field.Index.TOKENIZED));
break;
case FileType.Htm:
doc.Add(new Field("File", new StreamReader(file.Stream, System.Text.Encoding.Default)));
break;
default:
break;
}
writer.AddDocument(doc);
writer.Optimize();
writer.Close();
}
其中,把id 的index设为Field.Index.UN_TOKENIZED,差不多就是id做为主键,后面删除索引的时候,直接删除这个id就行
switch (file.FileType)就是根据附件类型,解析读取内容
2 搜索

/// <summary>
/// 搜索
/// </summary>
/// <param name="pSearchStr">查询字符</param>
/// <returns>返回结果集</returns>
public DataTable Search(string pSearchStr) {
if (!string.IsNullOrEmpty(pSearchStr)) {
IndexSearcher searcher = new IndexSearcher(this.GetIndexPath);
//单字段搜索
//QueryParser parser = new QueryParser("title", this.Analyzer);
//Query query = parser.Parse(this.TextBox2.Text.Trim());
//多字段搜索
Query query = MultiFieldQueryParser.Parse(new string[] { pSearchStr, pSearchStr } , new string[] { "Title", "File" }, this.Analyzer);
Hits h = searcher.Search(query);
Document doc;
//高亮显示
SimpleHTMLFormatter simpleHTMLFormatter = new SimpleHTMLFormatter("<font color=\"red\">", "</font>");
Highlighter highlighter = new Highlighter(simpleHTMLFormatter, new QueryScorer(query));
//关键内容显示大小设置
//highlighter.SetTextFragmenter(new SimpleFragmenter(400));
DataTable dt = new DataTable();
dt.Columns.Add("Id");//序号
dt.Columns.Add("FileId");//记录ID
dt.Columns.Add("Title");//标题
for (int i = 0; i < h.Length(); i++) {
doc = h.Doc(i);
#region 下载
//try {
// //string strFile=HttpUtility.UrlEncode( myTable.Rows[0]["FileName"].ToString(), System.Text.Encoding.GetEncoding("GB2312")).Replace("+"," ");
// string strFile = HttpUtility.UrlEncode(doc.GetField("title").StringValue(), System.Text.Encoding.UTF8);
// Response.AddHeader("Content-Disposition", "attachment;filename=" + strFile);
// Response.ContentType = ("application/unknown");
// byte[] myByte = doc.GetField("file").BinaryValue();
// Response.BinaryWrite(myByte);
// Response.End();
//}
//catch { }
#endregion
string title = doc.Get("Title");
//取出高亮显示内容
TokenStream tokenStream = (this.Analyzer).TokenStream("Title", new StringReader(title));
string newTitle = highlighter.GetBestFragments(tokenStream, title, 5, "

if (!string.IsNullOrEmpty(newTitle)) {
title = newTitle;
}
this.AddRow(dt, i + 1, doc.Get("FileId"), title);
}
searcher.Close();
return dt;
}
return null;
}
现在只对标题(title)和内容(file)做了索引,所以只对这两个字段进行搜索. 最后,返回一个DataTable,包括FileID(记录ID,以便下载附件)和Title(标题). 其中对搜索结果使用了高亮显示Highlighter.
3 删除索引

/// <summary>
/// 删除索引
/// </summary>
/// <param name="pID"></param>
public void Delete(string pID) {
IndexReader reader = IndexReader.Open(GetIndexPath);
Term aTerm = new Term("FileId", pID);
reader.DeleteDocuments(aTerm);
reader.Close();//必须,真正删除
}
先创建个Term,然后用IndexReader删除
4 其他一些辅助属性

#region 属性
string INDEX_STORE_PATH = "index";
/// <summary>
/// 获取/设置index目录
/// </summary>
public string IndexPath {
get {
return INDEX_STORE_PATH;
}
set {
INDEX_STORE_PATH = value;
}
}
/// <summary>
/// 换成物理地址
/// </summary>
private string GetIndexPath {
get {
return HttpContext.Current.Server.MapPath(INDEX_STORE_PATH);
}
}
Analyzer _analyzer = new ChineseAnalyzer();
/// <summary>
/// 获取/设置分析器
/// </summary>
public Analyzer Analyzer {
get {
return _analyzer;
}
set {
_analyzer = value;
}
}
#endregion
5 通过com组件读取office文档内容

#region 利用com组件读取office
/// <summary>
/// 判断文件是否存在
/// </summary>
/// <param name="pFileName"></param>
private void IsExists(string pFileName) {
if (!File.Exists(pFileName)) {
throw new ApplicationException("指定目录下的无该文件");
}
}
//获得word文件的文本内容
public string Doc2Text(string docFileName) {
IsExists(docFileName);
//实例化COM
Word.ApplicationClass wordApp = new Word.ApplicationClass();
object fileobj = docFileName;
object nullobj = System.Reflection.Missing.Value;
//打开指定文件(不同版本的COM参数个数有差异,一般而言除第一个外都用nullobj就行了)
Word.Document doc = wordApp.Documents.Open(ref fileobj, ref nullobj, ref nullobj,
ref nullobj, ref nullobj, ref nullobj,
ref nullobj, ref nullobj, ref nullobj,
ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj
);
//取得doc文件中的文本
string outText = doc.Content.Text;
//关闭文件
doc.Close(ref nullobj, ref nullobj, ref nullobj);
//关闭COM,关闭word程序
wordApp.Quit(ref nullobj, ref nullobj, ref nullobj);
GC.Collect();
//返回
return outText;
}
//获得excel文件的文本内容
public string Xls2Text(string xlsFileName) {
IsExists(xlsFileName);
Excel.Application xlsApp = new Excel.ApplicationClass();
object nullobj = System.Reflection.Missing.Value;
//打开Excel文档
Excel.Workbook excel = xlsApp.Workbooks.Open(xlsFileName, nullobj,
nullobj, nullobj, nullobj,
nullobj, nullobj, nullobj,
nullobj, nullobj, nullobj,
nullobj, nullobj, nullobj,
nullobj);
//遍历Excel工作表
Excel.Worksheet ews = null;
StringBuilder builder = new StringBuilder();
try
{
for (int k = 1; k <= excel.Worksheets.Count; k++)
{
ews = (Excel.Worksheet)excel.Worksheets[k];
//builder.Append(((Excel.Range)ews.UsedRange).Text);
if (ews.UsedRange.Value2 != null)
{
for (int i = 1; i <= ews.UsedRange.Cells.Rows.Count; i++)
{
for (int j = 1; j <= ews.UsedRange.Cells.Columns.Count; j++)
{
if (((object[,])(ews.UsedRange.Value2))[i, j] != null)
{
builder.Append(((object[,])(ews.UsedRange.Value2))[i, j]).Append("|");
}
}
}
}
}
}
catch (Exception ex)
{
throw ex;
}
finally
{
excel.Close(nullobj, nullobj, nullobj);
xlsApp.Quit();
GC.Collect();
}
return builder.ToString();
}
//获得PPT文件的文本内容
public string Ppt2Text(string pptFileName) {
IsExists(pptFileName);
PowerPoint.Application pptApp = new PowerPoint.ApplicationClass();
object nullobj = System.Reflection.Missing.Value;
PowerPoint.Presentation ppt = pptApp.Presentations.Open(pptFileName,
Microsoft.Office.Core.MsoTriState.msoTrue,
Microsoft.Office.Core.MsoTriState.msoFalse,
Microsoft.Office.Core.MsoTriState.msoFalse);
StringBuilder builder = new StringBuilder();
try
{
foreach (PowerPoint.Slide slide in ppt.Slides)
{
foreach (PowerPoint.Shape shape in slide.Shapes)
{
if (shape.TextFrame.HasText == Microsoft.Office.Core.MsoTriState.msoTrue)
{
builder.Append(shape.TextFrame.TextRange.Text);
}
}
}
}
catch (Exception ex)
{
throw ex;
}
finally {
ppt.Close();
pptApp.Quit();
GC.Collect();
}
return builder.ToString();
}
#endregion
最后看下Demo的界面
-------------------------------------------------------------------------
Lucene.net






转自:http://www.cnblogs.com/steven9801/archive/2011/12/29/2305736
相关问答
更多-
爱情故事,转载的也可以,要浪漫点的[2022-04-17]
一个男孩子每天都要去那个叫雪的女孩所经营的电话亭,给他的女朋友打电话。 男孩子通常把电话放到耳朵上,在拨号的时候总是按5201314的号码,还总是对着话筒说:“你好,我是星空,我在这很想你,干吗想你?爱你啊,真的爱你!时时刻刻想着你,你知道吗?”雪起先对男孩不很在意,后来男孩子在她的电话亭打电话的次数多了,雪就把这个男孩子记住了。 以后只要男孩子一进来,雪就把两部电话中的一部推给这个男孩子,然后雪在心里就会冒出男孩子想要说的记句话来:干吗想你?爱你啊!真的爱你!时时刻刻想着你,你知道吗?果然号码一拨 ... -
[转载]孩子是不是一定要上英语培训班[2021-12-23]
很高兴收到一名家长朋友的留言,家长写道:我是一个八岁男孩的家长,孩子从去年七月阅读原版《夏洛的网》,进步明显。此前孩子从未送外学习过,但经过现在的学习,孩子可以读出夏洛整本书,最好的是听力,E. B. 怀特的原声,随便任选一段,都可随听随懂,没有障碍... ... 这位小男孩,才八岁,也没上过培训班,仅仅半年多时间,能把原版《夏洛的网》讲读课学的这么好,我非常高兴。接着,这位家长又提到一些问题。比如,小朋友现在,不愿意去外面上培训班;孩子的英语发音不够准确... ...等等。类似这些问题,别的家长,也曾陆陆 ... -
转载:为什么使用ibatis而不用spring jdbcTemplate[2022-09-12]
第二:ibatis所有的sql都可以放在配置文件中,这样有利于sql的集中管理,特别是在sql tuning是很容易把得到所有的sql,如果使用spring jdbctemplate,那么难免要在sql adv上调试好了sql,然后在粘贴到java代码中,会有一大堆的StringObj+=和 StringBufferObj.append() ,如果sql 很长,那么总是copy , paste 也很烦,ibatis没有这样的问题。 第四:ibatis内置cache机制,同时还可以和osCache集成,cac ... -
android x86 安装方法!请勿转载[2022-05-17]
建议你装linux,androidx86啥软件都用不了。。。。。。至于linux,elementaryos最好! -
如何自动在wordpress文章增加版权和转载声明[2022-03-30]
我们一般都是了后台加自动添加版权,来防止别人采集我们的文章,那么如何设置自动在wordpress的文章中添加版权呢?首先我要先提到一下,之前和本文有密切联系的姊妹篇文章,就是在复制网站内容的时候,会自动带上网站的域名,这个小功能,同样也... -
[转载]如何彻底删除tomcat下的一个项目[2022-06-02]
不知道我有没有把问题想简单了,是不是应该把webapps下对应的文件夹删了就可以了。 work下面对应的也删掉 这个取决于你在tomcat下发布那个项目的方式。 首先是工程的根目录要删除,然后是工程相关的配置文件 (一般在jakarta-tomcat-5.0.28confCatalinalocalhost,版本是6.0.29的木有的)work下的也要删!!! 如果有报错“java.lang.IllegalArgumentException:Document base E:tomcatwebappsreglo ... -
请问博客园的文章怎么转载到自己的博客?[2022-04-29]
有的博客设置了转载权限的,只能复制了,没有其它的办法了 -
您应该将标记添加到单独的tag字段中。 典型的查询看起来像这样: content:(+honda +civic) +tag:red +tag:hatchback 前两个术语( honda和civic )由用户输入,而后两个术语( red和hatchback )将从标签列表中选择。 如果要支持包含空格的标记,则必须通过CharTokenizer : Lucene.Net支持短语来滚动自己的标记符?:在索引期间,字段 CharTokenizer 逗号分隔数据(原子地)标记化的最佳方法是什么? +tag:"5 ...