ASP.NET基于Ajax+Lucene构建搜索引擎的设计和实现

摘  要

通过搜索引擎从互联网上获取有用信息已经成为人们生活的重要组成部分,Lucene是构建搜索引擎的其中一种方式。搜索引擎系统是在.Net平台上用C#开发的,数据库是MSSQL Server 2000。主要完成的功能有:用爬虫抓取网页;获取有效信息放入数据库;通过Lucene建立索引;对简单关键字进行搜索;使用Ajax的局部刷新页面展示结果。

本文详细说明了系统开发的背景,开发环境,系统的需求分析,以及功能的设计与实现。同时讲述了搜索引擎的原理,系统功能,并探讨使用Ajax与服务器进行数据异步交互,从而改善现有的Web应用模式。

关键词Lucene.net;异步更新;Ajax;搜索引擎

2.1 全文搜索引擎

2.1.1 搜索引擎的分类

全文搜索引擎通过从互联网上提取的各个网站的信息(以网页文字为主)而建立的数据库中,检索与用户查询条件匹配的相关记录,然后按一定的排列顺序将结果返回给用户。从搜索来源的角度,全文搜索引擎又可细分为两种,一种是拥有自己的检索程序(Indexer),俗称“蜘蛛”(Spider)程序或“机器人”(Robot)程序,并自建网页数据库,搜索结果直接从自身的数据库中调用;另一种则是租用其他引擎的数据库,并按自定的格式排列搜索结果。

分类目录则是通过人工的方式收集整理网站资料形成数据库的,比如雅虎中国以及国内的搜狐、新浪、网易分类目录。另外,在网上的一些导航站点,也可以归属为原始的分类目录。

2.1.2 搜索引擎的工作原理

搜索引擎的原理,可以看作三步:从互联网上抓取网页,建立索引数据库,在索引数据库中搜索。

利用能够从互联网上自动收集网页的Spider程序,自动访问互联网,并沿着网页中的所有URL爬到其它网页,重复这过程,并把爬过的所有网页收集回来。然后建立索引数据库,由分析索引程序对收集回来的网页进行分析,提取相关网页信息(包括网页所在URL、编码类型、页面内容包含的关键词、关键词位置、生成时间、大小、与其它网页的链接关系等),然后用这些相关信息建立网页索引数据库。接下来在索引数据库中搜索排序,当用户输入关键词搜索后,由搜索系统程序从网页索引数据库中找到符合该关键词的所有相关网页。最后,由页面生成系统将搜索结果的链接地址和页面内容摘要等内容组织起来返回给用户。搜索引擎只能搜到它网页索引数据库里储存的内容。

2.2 Lucene与搜索引擎

Lucene是一个全文信息检索工具包,为应用程序提供索引和搜索功能。和Java Lucene兼容的Lucene.net可以用在.net平台。Lucene能够为文本类型的数据建立索引,所以你只要能把你要索引的数据格式转化的文本的,Lucene就能对你的文档进行索引和搜索。比如你要对一些HTML文档,PDF文档进行索引的话你就首先需要把HTML文档和PDF文档转化成文本格式的,然后将转化后的内容交给Lucene进行索引,然后把创建好的索引文件保存到磁盘或者内存中,最后根据用户输入的查询条件在索引文件上进行查询。不规定要索引的文档的格式也使Lucene能够适用于几乎所有的搜索应用程序。

2.3 索引和搜索

索引是现代搜索引擎的核心,建立索引是把数据源处理成非常方便查询的索引文件的过程。为什么索引这么重要呢,试想你现在要在大量的文档中搜索含有某个关键词的文档,那么如果不建立索引的话你就需要把这些文档顺序的读入内存,然后检查这个文章中是不是含有要查找的关键词,这样的话就会耗费非常多的时间,想想搜索引擎可是在毫秒级的时间内查找出要搜索的结果的。这就是由于建立了索引的原因,你可以把索引想象成这样一种数据结构,他能够使你快速的随机访问存储在索引中的关键词,进而找到该关键词所关联的文档。Lucene采用的是一种称为反向索引(inverted index)的机制。反向索引就是说我们维护了一个词/短语表,对于这个表中的每个词/短语,都有一个链表描述了有哪些文档包含了这个词/短语。这样在用户输入查询条件的时候,就能非常快的得到搜索结果。我们将在本系列文章的第二部分详细介绍Lucene的索引机制,由于Lucene提供了简单易用的API,所以也可以非常容易的使用Lucene对文档实现索引的建立。

2.4 Ajax技术

Ajax全称为“Asynchronous JavaScript and XML”(异步JavaScript和XML),是指一种创建交互式网页应用的网页开发技术。Ajax技术是目前在浏览器中通过JavaScript脚本可以使用的所有技术的集合。包括:HTML和CSS,使用文档对象模型DOM作动态显示和交互,使用XML做数据交互和操作,使用XMLHttpRequest进行异步数据接收,使用JavaScript将它们绑定在一起。

Ajax技术之中,核心的技术就是XMLHttpRequest,它最初的名称叫做XMLHTTP,是微软公司为了满足开发者的需要,1999年在IE5.0浏览器中率先推出的。后来这个技术被上述的规范命名为XMLHttpRequest。它正是Ajax技术之所以与众不同的地方。简而言之,XMLHttpRequest为运行于浏览器中的JavaScript脚本提供了一种在页面之内与服务器通信的手段。页面内的JavaScript可以在不刷新页面的情况下从服务器获取数据,或者向服务器提交数据。XMLHttpRequest的出现为Web开发提供了一种全新的可能性,甚至整个改变了人们对于Web应用由什么来组成的看法。

5.1 开发环境

开发平台的选择:本系统的开发平台选择微软公司的.NET,开发工具采用ASP.NET。.NET是Microsoft面向Web服务的平台,由框架、Web服务、.NET企业服务器等几部分组成,提供涉及面较广、功能较全面的解决方案。数据库选择:根据需求分析选择了MSSQL Server 2000。

5.2 关键代码详解

5.2.1 代码结构

如图6:

在网页爬虫Console端应用程序里输入一个有效的URL后这部份就开始从第一个URL开始遍历相关的链接并把相关的信息写入到网页数据存储数据库里,然后就由索引生成程序读取网页数据存储数据库,对每条记录生成索引记录,存放于生成的索引库文件里。生成索引需要调用Lucene.Net类。索引生成后在查询部分就能够在网页上输入关键字,对刚才抓取的信息的查询。并可以定位到信息的出处。下面对各部分关键代码进行详解。

5.2.2 爬虫部分

这部份的功能就是从输入的URL开始遍历各个相关的网页,它包括三个功能模块:网页抓取模块、网页减肥模块、爬虫维持模块。

首先定义一些变量用于保存抓取到的网页信息,urlList用于保存当前页面上的URL集合。然后根据全局变量url抓取此URL的网页信息到字节流变量里,经过转码后读取到变量PageString里,下步通过函数GetHttpUrl(PageString)对PageString中的URL标记进行提取并返回到urlList变量里,函数GetTitle(PageString)、parseScript(PageString)、parseHtml(PageString)、parseChar(Content)分别对网页信息变量获取标题、去除脚本块、去除HTML标记、去除特殊字符操作。再下步就是对获取到的标题、网页内容、链接等信息调用数据库操作通用类DAI保存到数据库里,这就实现了一个网页的抓取。再下步就是循环的对获取到的URL列表创建线程,针对每个URL来循环的执行上面的网页信息的抓取操作。具体代码如下:

private static void UrlThread()

{

       String  title="";

       String  Content="";

       String  mata="";

       string  URL="";

       string[]  urlArr = null;

       StringBuilder urlList = new StringBuilder();

       System.Net.WebClient Client=new System.Net.WebClient();

       try

       {

              Stream strm=null;

              try

              {//读取一个URL的信息到流变量里

                     Stream   strm=Client.OpenRead(url); 

       }

              catch

              {

                     console.WriteLine("url无法找到!");

                     return;

              }

              StreamReader sr=new StreamReader(strm,Encoding.GetEncoding("gb2312"));

              String PageString=sr.ReadToEnd();//从流中读取网页信息到字符串变量中

              strm.Close();

              urlList = GetHttpUrl(PageString);

              title=GetTitle(PageString);

              Content = parseScript(PageString);  //去掉脚本的网页文本                               

              Content=parseHtml(PageString);   //得到去了HTML标签的网页文本  

              URL=url;

              mata="";       

              Content = parseChar(Content);                                

              if((title != "" || title != string.Empty) && URL != "")

              {

                     DAI.RunSqlNonQuery("insert into WebContent(url,content,title,mata)                                 values('"+URL+"','"+Content+"','"+title+"','"+mata+"')");

                     Console.WriteLine("对url:"+URL+"相关信息写入数据库成功!");

              }

              else

              {

                     Console.WriteLine("对url:"+URL+"相关信息写入数据库失败!");

              }

              urlArr=urlList.ToString().Split('|');

              //对前面获取的URL列表循环的创建线程再执行本方法实现爬虫的维持

              for(int i=0;i<urlArr.Length;i++)

              {

                     url=urlArr[i];

                     if(url == "" || url == null || url == string.Empty)

                            continue;

                     Thread th = new Thread(new ThreadStart(UrlThread));

                     th.Start();                    

              }                         

       }

       catch{}

}

5.2.3索引生成

这部分包含对文本的索引生成以及对数据库数据的索引生成,下面只对数据库索引生成的关键代码进行介绍:

下面这段代码实现对数据库里存储的记录创建索引。主要通过Lucene提供的方法来协助实现。

public Indexer(string indexDir)

{

       #region Lucene Code

首先通过标准分词定义了一个索引写入器

       IndexWriter writer = new IndexWriter(indexDir, new StandardAnalyzer(), true);     

在创建索引库时,会合并多个Segments文件。此方式有助于减少索引文件数量,减少同时打开的文件数量。

writer.SetUseCompoundFile(false);

//删除以前生成的索引文件。

System.IO.Directory.Delete(iDexDir,true);

#endregion

DateTime start = DateTime.Now;

DoIndexByDB(writer);//

DateTime end = DateTime.Now;

int docNum = writer.DocCount();

Console.WriteLine("Index Finished. {0} Documents takes {1} second.",

docNum, ((TimeSpan)(end - start)).TotalSeconds);

writer.Optimize();

writer.Close();

}

使用Lucene提供的方法对数据库中的每条记录建立索引实现如下:

Document doc = new Document();

Console.WriteLine("Indexing {0} ", row["title"].ToString());

doc.Add(Field.Text("contents", row["content"].ToString()));

doc.Add(Field.Keyword("title", row["title"].ToString()));

doc.Add(Field.Keyword("mata",row["mata"].ToString()));

doc.Add(Field.Keyword("CreateDate",row["CreateDate"].ToString()));

doc.Add(Field.Keyword("Url",row["Url"].ToString()));

doc.Add(Field.Keyword("ID",row["ID"].ToString()));

writer.AddDocument(doc);

5.2.4页面查询

这部分主要完成的功能是获取前台表单中输入的关键字,在程序中获取查询结果,最后把列表显示在前台页面。

Ajax在此部分中被使用到,它完成的功能是部分刷新页面,不需整个页面的重新加载。为了方便的在程序中使用Ajax,此系统引用了封装完善的Ajax类库。在程序中注册后,在html里就可以使用Javascript来调用后台的程序。选取部分代码来说明:

首先在页面后台程序中进行Ajax注册,代码如下:

private void Page_Load(object sender, System.EventArgs e)

              {

                     //ajax注册

                     AjaxPro.Utility.RegisterTypeForAjax(typeof(Search));                   

              }

如果前台Javascript需要调用某个方法,那就在那个函数前加上[AjaxPro.AjaxMethod],表示此方法属于ajax应用。

[AjaxPro.AjaxMethod]

public string SearchResult(string keywords,string pageNo)

{

其中,前台所存在的文字的代码如下:

StringBuilder sb = new StringBuilder();

sb.Append("<tr><td>结果数:"+result+"&nbsp;所用时间:"+t+"毫秒</td></tr>");

前台显示结果记录的代码,动态生成table标签,如下:

for(int i = startNum ; i < endNum; i++)

{

在显示内容中,仍然使用到了Lucene提供的类,可以方便的从所建立的索引文档中获取网址,网页标题,内容,时间。

Document doc = hits.Doc(i);

content=doc.Get("contents");

content=content.Replace(keywords,"<font color=red>"+keywords+"</font>");

sb.Append("<tr class="+c+">");

sb.Append("<td><a href="+doc.Get("Url")+">"+doc.Get("title")+"</a></td>");

sb.Append("</tr>");   

sb.Append("<tr class="+c+">");

sb.Append("<td>"+content+"<br>"+doc.Get("CreateDate")+"</td>");

sb.Append("</tr>");

}

}

结    论

本课题主要探讨了搜索引擎的原理,介绍了原理和过程,并给出了使用Lucene与Ajax实现的方法。该系统引入了当前用于构建搜索引擎的Lucene工具包,在.Net环境下,充分利用Lucene所提供的工具,完成搜索引擎的基本功能。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/543974.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【数据分析】AHP层次分析法

博主总结&#xff1a;根据每个方案x各准则因素权重累加结果 对比来选择目标。数据主观性强 简介 AHP层次分析法是一种解决多目标复杂问题的定性和定量相结合进行计算决策权重的研究方法。该方法将定量分析与定性分析结合起来&#xff0c;用决策者的经验判断各衡量目标之间能…

Flutter - iOS 开发者速成篇

首先 安装FLutter开发环境&#xff1a;M1 Flutter SDK的安装和环境配置 然后了解Flutter和Dart 开源电子书&#xff1a;Flutter实战 将第一章初略看一下&#xff0c;你就大概了解一下Flutter和Dart这门语言 开始学习Dart语言 作为有iOS经验的兄弟们&#xff0c;学习Dart最快…

【蓝桥】二分法

二分法 简介&#xff1a; 网上模板很多&#xff0c;看得眼花缭乱&#xff0c;搞得不知道用哪种好&#xff0c;我自己就用这种吧&#xff0c;这是前几天看那道冶炼金属那题看到得模板&#xff0c;这个模板应该也适用于很多题了(闭区间) 寻找靠左的数 while(l<r) {int mid…

卷积神经网络(LeNet5实现对Fashion_MNIST分类

参考6.6. 卷积神经网络&#xff08;LeNet&#xff09; — 动手学深度学习 2.0.0 documentation (d2l.ai) ps&#xff1a;在这里预备使用pythorch 1.对 LeNet 的初步认识 总的来看&#xff0c;LeNet主要分为两个部分&#xff1a; 卷积编码器&#xff1a;由两个卷积层组成; …

ssm049基于Vue.js的在线购物系统的设计与实现+vue

在线购物系统 摘 要 随着科学技术的飞速发展&#xff0c;各行各业都在努力与现代先进技术接轨&#xff0c;通过科技手段提高自身的优势&#xff1b;对于在线购物系统当然也不能排除在外&#xff0c;随着网络技术的不断成熟&#xff0c;带动了在线购物系统&#xff0c;它彻底改…

Ubuntu快捷安装MySQL

更新包列表 sudo apt update 安装mysql sudo apt install mysql-server 启动mysql // 启动mysql sudo service mysql start// 关闭mysql sudo service mysql stop// 重启mysql sudo service mysql restart 连接mysql // 初始安装无密码&#xff0c;直接连接即可&#xf…

13.多通道视频流缓存以及显示架构

1 简介 多通道视频流缓存以及显示架构是一个在数字图像处理中很基础也很重要的一个架构。在图像拼接以及高分辨率图像显示方面应用范围较为广泛。本文将介绍一个四通道的图像显示。可以四个图像信息输入以及拼接到一个显示屏里面。使用的开发板为A7 2 框架图 架构图如下图所示…

Python杂记--使用asyncio构建HTTP代理服务器

Python杂记--使用asyncio构建HTTP代理服务器 引言基础知识代码实现 引言 本文将介绍 HTTP 代理的基本原理&#xff0c;并带领读者构建一个自己的 HTTP 代理服务器。代码中不会涉及到任何第三方库&#xff0c;全部由 asyncio 实现&#xff0c;性能优秀&#xff0c;安全可靠。 基…

云服务器安装Mysql、MariaDB、Redis、tomcat

前置工作 进入根目录 cd / 进入/user/local文件夹 上传压缩包 rz 压缩包 Mysql 1.下载并安装MySQL官方的 Yum Repository wget http://dev.mysql.com/get/mysql-community-release-el7-5.noarch.rpm rpm -ivh mysql-community-release-el7-5.noarch.rpm yum install mysql-…

ssh爆破服务器的ip-疑似肉鸡

最近发现自己的ssh一直有一些人企图使用ssh暴力破解的方式进行密码破解.就查看了一下,真是网络安全太可怕了. 大家自己的服务器密码还是要设置好,管好,做好最基本的安全措施,不然最后只能沦为肉鸡. ssh登陆日志可以在/var/log下看到,ubuntu的话为auth.log,centos为secure文件 查…

设计模式代码实战-桥接模式

1、问题描述 小明家有一个万能遥控器&#xff0c;能够支持多个品牌的电视。每个电视可以执行开机、关机和切换频道的操作&#xff0c;请你使用桥接模式模拟这个操作。 输入示例 6 0 2 1 2 0 4 0 3 1 4 1 3 输出示例 Sony TV is ON TCL TV is ON Switching Sony TV channel S…

Oracle 19c RAC 补丁升级 补丁回退

补丁升级流程 补丁升级 停止集群备份家目录 两节点分别操作 cd /u01/app/19.3.0/grid/bin/ crsctl stop crs tar -zcvf /u01/app.tar.gz /u01/app /u01/app/19.0.0/grid/bin/crsctl start crs 两节点OPatch替换 --- 表示 root 用户&#xff0c;$ 表示 Oracle 用户提示符&#…

NLP_知识图谱_图谱问答实战

文章目录 图谱问答NERac自动机实体链接实体消歧 多跳问答neo4j_graph执行流程结构图![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/1577c1d9c9e342b3acbf79824aae980f.png)company_data![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/20f567d877c743b…

python爬虫-----Selenium (第二十二天)

&#x1f388;&#x1f388;作者主页&#xff1a; 喔的嘛呀&#x1f388;&#x1f388; &#x1f388;&#x1f388;所属专栏&#xff1a;python爬虫学习&#x1f388;&#x1f388; ✨✨谢谢大家捧场&#xff0c;祝屏幕前的小伙伴们每天都有好运相伴左右&#xff0c;一定要天天…

(一)基于IDEA的JAVA基础15

还是先来说一下: Arrays工具类 Arrays是java.util包提供的工具类 提供了操作数组的方法&#xff0c;如排序,查询等。 如排序(升序)使用sort方法 语法: Arrays.sort(数组名)&#xff1b; 还是直接写来看看: public class Test01 { public static void main(String[] args)…

攻防世界12-baby_web

12-baby_web 题目说想想初始页面是哪个&#xff0c;一般都是index.php&#xff0c;然后如题分析即可。 我们在链接后面拼接上/index.php&#xff0c;返回后发现界面又回到了1.php&#xff0c;有可能是重定向。 我们点击检查-网络&#xff0c;发现没有index的请求&#xff0c;…

系统架构最佳实践 -- 供应链系统架构

供应链系统是现代企业管理中不可或缺的一部分&#xff0c;它涉及到从原材料采购到产品销售的整个生产流程。一个高效的供应链系统可以帮助企业实现成本控制、库存优化和客户满意度提升等目标。在本文中&#xff0c;我们将讨论供应链系统的设计与实践。 一、供应链系统设计 业务…

数字乡村创新实践探索农业现代化与乡村振兴新路径:科技赋能农村全面振兴与农民幸福新篇章

随着信息技术的飞速发展&#xff0c;数字乡村成为推动农业现代化与乡村振兴的重要战略举措。科技赋能下的数字乡村创新实践&#xff0c;不仅提升了农业生产的智能化水平&#xff0c;也为乡村治理和农民生活带来了翻天覆地的变化。本文旨在探讨数字乡村创新实践在农业现代化与乡…

数据库数据恢复—Sql Server数据库文件丢失如何恢复数据?

服务器数据恢复环境&#xff1a; 一台安装windows server操作系统的服务器。一组由8块硬盘组建的RAID5&#xff0c;划分LUN供这台服务器使用。 在windows服务器内装有SqlServer数据库。存储空间LUN划分了两个逻辑分区。 服务器故障&初检&#xff1a; 由于未知原因&#xf…