小妖女 发表于 2015-1-16 22:43:10

ASP.NET网站制作之Lucene.net 完成全文搜刮

我见过java运行在手机上,包括很廉价的山寨手机,但是却暂时没发现.net在手机上有什么作为。wp7可能是个转机,但是按照《Java的跨平台就是一句谎言。那.net的跨平台也当之无愧是一句谎言。全文搜刮忙了几天终究完成一个复杂的全文搜刮在此回忆总结一下
本文先容一下Lucene.Net是甚么?Lucene.Net能作甚么?和怎样做的成绩?最初给出Lucene.Net完成全文搜刮的一个示例
1、Lucene.Net是甚么?
Lucene.net后来是一个开源项目然后转向贸易化,也在Lucene.net2.0已公布,不外是要moneyD,Lucene.net的运气有点相似于FreeTextBox,它在1.6.5版本以后公布的2.0入手下手了贸易线路,2.0供应了DLL体例的收费版本,源代码版本则必需购置贸易的允许licence;不外它留下了1.6.5版本的源代码,仍是能够看到年夜部分的外部细节,但2.0版本中增加的对Mozilla扫瞄器的撑持部分只要经由过程它天生的HTML和JavaScript剧本往窥伺。
Lucene是Java天下中经常使用的索引API,利用它供应的办法能够为文本材料创立索引,并供应检索。(参考:NLucene和Lucene.NET)NLucene是第一个的.net移植,也是一个有.net作风的版本,利用.net的定名标准和类库计划。不外NLucene项目标leader因为精神缘故原由,只公布了1.2beta版本。Lucene.NET项目呈现后,NLucene就没有新的企图了。
Lucene.NET现在号称要做up-to-date的.netLucene移植,它只在定名方面采取了.net的倡议,次要方针偏向于和JavaLucene兼容:一个是索引格局兼容,到达能够配合事情的目标;一个是定名靠近(只相差很少,好比巨细写等),目标是能够便利开辟者利用JavaLucene相干的代码和材料。
不知甚么时分Lucene.NET项目已保持了开源企图,转向了贸易。它竟然把SourceForge上已开源的文件也删除。与此同时,SourceForge上又呈现了dotLucene项目,出于对Lucene.NET的抗议,dotLucene几近将Lucene.NET的代码一成不变放在下面作为他们的出发点。(https://sourceforge.net/forum/forum.php?thread_id=1153933&forum_id=408004)。
说白了Lucene.Net就是是一个信息检索的函数库(Library),使用它你能够为你的使用加上索引和搜刮的功效.
Lucene的利用者不用深切懂得有关全文检索的常识,仅仅学会利用库中的几个类,晓得怎样挪用Library中的函数,就能够为你的使用完成全文检索的功效.
不外万万别希冀Lucene是一个象google和百度那样的搜刮引擎,它仅仅是一个工具,一个Library.你也能够把它了解为一个将索引,搜刮功效封装的很好的一套复杂易用的API.使用这套API你能够做良多有关搜刮的事变,并且很便利,它能够满意你对一个使用做复杂的全文搜刮,作为使用的开辟者(非专业搜刮引擎开辟者)来讲,它的功效足以满意你。
2、Lucene.Net能够作甚么?
Lucene能够对任何的数据做索引和搜刮.Lucene不论数据源是甚么格局,只需它能被转化为笔墨的情势,就能够被Lucene所剖析使用.也就是说不论是MSword,Html,pdf仍是其他甚么情势的文件只需你能够从中抽掏出笔墨情势的内容就能够被Lucene所用.你就能够用Lucene对它们举行索引和搜刮.
3、利用Lucene.Net怎样做?
复杂的回结为:创立索引,和利用索引,个中创立索引就是将要搜刮的数据源的那些信息作为我们的关头信息来存储大概是剖析,为搜刮留下标志就象Word内里创立目次(团体了解),利用索引就是在搜刮的时分依据索引的信息来剖析数据源将我们必要的信息提掏出来。
详细请看一下示例:
创立索引的类
publicclassIntranetIndexer
{
/**/////索引写进器
privateIndexWriterwriter;
//要写进索引的文件的根目次
privatestringdocRootDirectory;
//要婚配的文件格局
privatestring[]pattern;
/**////<summary>
///初始化一个索引写进器writer,directory为创立索引的目次,true代表假如不存在索引文件将从头创立索引文件,假如已存在索引文件将覆写索引文件
///</summary>
///<paramname="directory">传进的要创立索引的目次,注重是字符串值,假如目次不存在,他将会被主动创立</param>
publicIntranetIndexer(stringdirectory)
{
writer=newIndexWriter(directory,newStandardAnalyzer(),true);
writer.SetUseCompoundFile(true);
}

publicvoidAddDirectory(DirectoryInfodirectory,string[]pattern)
{
this.docRootDirectory=directory.FullName;
this.pattern=pattern;
addSubDirectory(directory);
}

privatevoidaddSubDirectory(DirectoryInfodirectory)
{
for(inti=0;i<pattern.Length;i++)
{
foreach(FileInfofiindirectory.GetFiles(pattern))
{
AddHtmlDocument(fi.FullName);
}
}
foreach(DirectoryInfodiindirectory.GetDirectories())
{
addSubDirectory(di);
}
}

publicvoidAddHtmlDocument(stringpath)
{
stringexname=Path.GetExtension(path);
Documentdoc=newDocument();

stringhtml;
if(exname.ToLower()==".html"||exname.ToLower()==".htm"||exname.ToLower()==".txt")
{
using(StreamReadersr=newStreamReader(path,System.Text.Encoding.Default))
{
html=sr.ReadToEnd();
}
}
else
{
using(StreamReadersr=newStreamReader(path,System.Text.Encoding.Unicode))
{
html=sr.ReadToEnd();
}
}
intrelativePathStartsAt=this.docRootDirectory.EndsWith("")?this.docRootDirectory.Length:this.docRootDirectory.Length+1;
stringrelativePath=path.Substring(relativePathStartsAt);
stringtitle=Path.GetFileName(path);

//判别如果网页则往标签不然不必
if(exname.ToLower()==".html"||exname.ToLower()==".htm")
{
doc.Add(Field.UnStored("text",parseHtml(html)));
}
else
{
doc.Add(Field.UnStored("text",html));
}
doc.Add(Field.Keyword("path",relativePath));
//doc.Add(Field.Text("title",getTitle(html)));
doc.Add(Field.Text("title",title));
writer.AddDocument(doc);
}
/**////<summary>
///往除网页中的标签
///</summary>
///<paramname="html">网页</param>
///<returns>前往往除后的网页文本</returns>
privatestringparseHtml(stringhtml)
{
stringtemp=Regex.Replace(html,"<[^>]*>","");
returntemp.Replace("","");
}
/**////<summary>
///猎取网页题目
///</summary>
///<paramname="html"></param>
///<returns></returns>
privatestringgetTitle(stringhtml)
{
Matchm=Regex.Match(html,"<title>(.*)</title>");
if(m.Groups.Count==2)
returnm.Groups.Value;
return"文档题目未知";
}
/**////<summary>
///优化索引并封闭写进器
///</summary>
publicvoidClose()
{
writer.Optimize();
writer.Close();
}
}
起首创建Document工具,然后为Document工具增加一些属性Field.你能够把Document工具当作是假造文件,未来将今后猎取信息.而Field则当作是形貌此假造文件的元数据(metadata).个中Field包含四个范例:Keywork
该范例的数据将不被剖析,而会被索引并保留保留在索引中.

UnIndexed
该范例的数据不会被剖析也不会被索引,可是会保留在索引.

UnStored
和UnIndexed恰好相反,被剖析被索引,可是不被保留.

Text
和UnStrored相似.假如值的范例为string还会被保留.假如值的范例为Reader就不会被保留和UnStored一样.

最初将每个Document增加到索引傍边。
上面是对索引举行搜刮

//创立一个索引器
IndexSearchersearcher=newIndexSearcher(indexDirectory);
//剖析索引的text字段以便搜刮
Queryquery=QueryParser.Parse(this.Q,"text",newStandardAnalyzer());
//将搜刮了局放在hits中
Hitshits=searcher.Search(query);
//统计搜刮的总纪录数
this.total=hits.Length();
//高亮显现
QueryHighlightExtractorhighlighter=newQueryHighlightExtractor(query,newStandardAnalyzer(),"<fontcolor=red>","</font>");
第一步使用IndexSearcher翻开索引文件用于前面搜刮,个中的参数是索引文件的路径.
第二步利用QueryParser将可读性较好的查询语句(好比查询的词lucene,和一些初级体例luceneAND.net)转化为Lucene外部利用的查询工具.
第三步实行搜刮.并将了局前往到hits汇合.必要注重的是Lucene并非一次将一切的了局放进hits中而是接纳一次放一部分的体例.出于空间思索.
然后将搜刮的了局举行处置并在页面上显现出来:
for(inti=startAt;i<resultsCount;i++)
{

Documentdoc=hits.Doc(i);

stringpath=doc.Get("path");
stringlocation=Server.MapPath("documents")+""+path;
stringexname=Path.GetExtension(path);

stringplainText;
stringstr=doc.Get("title");
if(exname==".html"||exname==".htm"||exname==".txt")
{
using(StreamReadersr=newStreamReader(location,System.Text.Encoding.Default))
{
plainText=parseHtml(sr.ReadToEnd());
}
}
else
{
using(StreamReadersr=newStreamReader(location,System.Text.Encoding.Unicode))
{
plainText=sr.ReadToEnd();
}
}

//DataTable增加行
DataRowrow=this.Results.NewRow();
row["title"]=doc.Get("title");
stringIP=Request.Url.Host;//猎取服务器IP
//Request.Url.Port;
row["path"]=@"http://"+IP+"/WebUI/Search/documents/"+path;
row["sample"]=highlighter.GetBestFragments(plainText,80,2,"");
this.Results.Rows.Add(row);
}
searcher.Close();//封闭搜刮器
想对Lucene.Net举行更初级,更周全,更深条理懂得的请参阅一下网站:
http://www.alphatom.com/
http://blog.tianya.cn/blogger/view_blog.asp?BlogName=aftaft
说句实话,Java跨平台根本就不是外行人想想的那种,一次编译,处处运行。

活着的死人 发表于 2015-1-25 14:41:14

代码的可重用性差:由于是面向结构的编程方式,并且混合html,所以可能页面原型修改一点,整个程序都需要修改,更别提代码重用了。

冷月葬花魂 发表于 2015-2-2 22:31:11

CGI程序在运行的时候,首先是客户向服务器上的CGI程序发送一个请求,服务器接收到客户的请求后,就会打开一个新的Process(进程)来执行CGI程序,处理客户的请求。CGI程序最后将执行的结果(HTML页面代码)传回给客户。

小女巫 发表于 2015-2-8 15:54:00

主流网站开发语言之PHP:PHP的全名非常有趣,它是一个巢状的缩写名称——“PHP:HypertextPreprocessor”,打开缩写还是缩写。PHP是一种HTML内嵌式的语言(就像上面讲的ASP那样)。而PHP独特的语法混合了C,Java,Perl以及PHP式的新语法。它可以比CGI或者Perl更快速地执行动态网页。

金色的骷髅 发表于 2015-2-25 20:03:17

当然我们在选择Asp.net主机是,除了要考虑服务提供商在版本是否是实时更新以外,机房的环境和配置也是非常重要的,通常选择骨干网的机房,在速度和稳定性上会非常有保证。

柔情似水 发表于 2015-3-8 02:08:18

这也就是最近几年来随着各种新的后台技术的诞生,CGI应用在Internet上越来越少的原因。CGI方式不适合大访问量的应用。

乐观 发表于 2015-3-15 19:51:14

如今主流的Web服务器软件主要由IIS或Apache组成。IIS支持ASP且只能运行在Windows平台下,Apache支持PHP,CGI,JSP且可运行于多种平台,虽然Apache是世界使用排名第一的Web服务器平台。
页: [1]
查看完整版本: ASP.NET网站制作之Lucene.net 完成全文搜刮