Lucene.Net 站内搜索

Lucene.Net 站内搜索

一  全文检索:

like查询是全表扫描(为性能杀手)
Lucene.Net搜索引擎,开源,而sql搜索引擎是收费的
Lucene.Net只是一个全文检索开发包(只是帮我们存数据取数据,并没有界面,可以看作一个数据库,只能对文本信息进行检索)
Lucene.Net原理:把文本切词保存,然后根据词汇表的页来找到文章

二  分词算法:

//一元分词算法(引用Lucene.Net.dll)

 一元分词算法

//二元分词算法(CJK:China Japan Korean 需要再引用CJKAnalyzer.cs/CJKTokenizer.cs)

 二元分词算法

//基于词库的分词算法(盘古分词算法)

打开PanGu4Luene\WebDemo\Bin,将Dictionaries添加到项目根路径(改名Dict),对于其下的文件,在其属性里,输出目录修改为如果较新则复制
  添加PanGu.dll的引用(如果直接引用PanGu.dll则必须不带PanGu.xml)
  添加PanGu4Luene\Release中PanGu.Luene.Analyzer.dll的引用

其中PanGu_Release_V2.3.1.0\Release\DictManage.exe可以查看Dict.dct二进制词库,既可以查看词汇也可以加入词汇

 盘古分词算法

三  写入索引 

Luene.Net写入类介绍

打开文件夹,指定要写入的文件夹
文件加锁,避免两个人同时写入文件(并发)
判断是否文件中有数据,有的话就更新数据,没有就创建
逐一读取待读文件中文本并写入文档
写之后进行close,则表示解锁,可以由其他人写入(加锁写入过程中程序出现bug需要强制解锁时可能出问题)
各种类的作用:
Directory保存数据:FSDirectory(文件中),RAMDirectory(内存中)
IndexReader对索引库进行读取的类,IndexWriter对索引库进行写的类
IndexReader的bool IndexExists(Directory directory)判断目录是否是一个索引目录
IndexWriter的bool IsLocked(Directory directory)判断目录是否是锁定的
IndexWriter在进行写操作时会自动加锁,close的时候会自动解锁.IndexWriter.Unlock方法手动解锁(比如还没来得及close IndexWriter程序就崩溃了,可能造成一直被锁定)
IndexWriter(Directory dir,Analyzer a,bool create,MaxFieldLength mfl)写入哪个文件夹,采用什么分词算法,是否是创建,最大大小
void AddDocument(Document doc),向索引中添加文档
Add(Field field)向文档中添加字段
DeleteAll()删除所有文档,DeleteDocuments按照条件删除文档
File类得构造函数 Field(string name,string value,Field.Store store,Field.Index index,Field.TermVector termVector)
上面依次表示:(字段名,字段值,是否把原文保存到索引中,index表示如何创建索引(Field.Index需要进行全文检索,NOT_ANALYZED不需要的),termVector表示索引词之间的距离,超出则关联度低)
处理并发(写的时候只能逐一写入):用消息队列保证只有一个程序(线程)对索引操作,其他程序不直接进行索引库的写入,而是把要写入的数据放入消息队列,由单独的程序从消息队列中取数据进行索引库的写入

文章在新增和编辑时写入索引:

  引用4个ServiceStack的dll用于队列

引用Quartz.dll/Common.Logging.dl用于定时任务

引用Lucene.Net.dll/PanGu.dll/PanGu.Lucene.Analyzer.dll用于写入索引

添加Dictionary改名Dict,旗下文件修改为如果较新则复制

 文章新增或编辑时入队列

 文章出队列写入索引

写入索引如果报错:

未能加载文件或程序集“PanGu, Version=2.3.0.0, Culture=neutral, PublicKeyToken=null”
或它的某一个依赖项。系统找不到指定的文件。

原因:

执行这个写入索引的令一个程序也需要引用PanGu.dll,最先执行写入索引的程序与后面真正类所在的索引是相互依赖的。

四  文章搜索:

query.Add(new Term("字段名","关键词"))
query.Add(new Term("字段名2","关键词2"))
类似于:where 字段名contains关键词 and 字段名2contains关键词2
PhraseQuery用于进行多个关键词的检索
PhraseQuery.SetSlop(int slop)用来设置单词之间的最大距离
BooleanQuery可以实现字段名contains关键词or字段名2contains关键词2

搜索时所采用的分词算法必须和生成索引时一致,即盘古分词算法

总条数 totalSize = collector.GetTotalHits()

查询结果集合应该是从(pagenum-1)*5,pagenum*5,但是collector.TopDocs(m,n)的m是从0开始、n是条数

 NewsController.ashx?action=search

五  写入索引优化:

通过多线程避免界面卡死:

因为耗时操作会阻塞主进程,所以需要把耗时操作放入子线程

因为主线程关闭,则子线程也会关闭,所以需要把子线程设置为后台子线程,这样主线程关闭,子线程会继续

示例:

 testThread.Form1.cs

实例:

//定时任务,子进程中出队列,然后写入文章索引,关闭窗口时终止子进程(出队列)和quartz.net进程
首先,启动窗体,执行定时任务,而定时的任务是进行新闻的出队列
然后,新闻的出队列是耗时操作,需要委托子进程,并设为后台进程,然后开始执行进程,其中出队列进程的控制由while(IsRunning)控制,先预先设置IsRunning=true
IsRunning = true;
Thread thread = new Thread(RunScan);//委托给子线程去RunScan
thread.IsBackground = true;//该子线程为后台线程
thread.Start();//执行该后台子线程,去执行RunScan方法
然后,执行出队列这个后台子进程
public static bool IsRunning { get; set; }//是否继续线程
public void RunScan()
{
while (IsRunning)//一旦窗体关闭,IsRunning=false,该进程终止
{...
然后,一直执行这个子进程,直到窗体被关闭,这时设置IsRunning=false使还在执行的这个后台子进程Thread的RunScan()终止,同时还需终止后台Quartz.net进程,避免窗体关闭而进程还在
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
NewsIndexer.IsRunning = false;//终止后台子进程RunScan方法
SendNewRegisterUM.schedWNI.Shutdown();//还需要终止后台Quartz.net进程,避免窗体已关闭,但是进程依然在
}

 Timer.NewsIndex.cs

 TimerForm.FormMain.cs

获取html的InnerText

搜索出来的不仅只是Title,还需要预览一部分内容body
用Lucene.net放入索引的时候需要过滤html标签
解决索引中body中全是html标签的问题,不利于搜索,很多垃圾信息,显示不方便。
使用HtmlAgilityPack进行innerText处理.
考虑文章编辑\重新索引等问题,需要先把旧的文档删除,再增加新的(等价于update)HTML解析器:输入一个html文档,提供对html文档操作的接口
开发包HtmlAgilityPack.1.4.0.zip,用于把html标签进行innerText后再放入索引库

引用 HtmlAgilityPack.dll

示例:

 示例

实例:

 实例

一键建立新闻索引:

入队列:

如果新闻太多,应该分批次进行入队列建立索引

 NewsController.ashx

 NewsBLL.cs

出队列:

每次出队列都进行一次索引路径的打开读取和关闭,效率低

全部出队列之前先打开索引目录,之后才关闭索引目录,最后才等待下一次client的队列中新数据

每次出队列加入检索索引之前,都需要删除文档索引中的相同id的文档索引,因为"编辑新闻"和"一键重建全文索引"都会再次加入同id的索引

 Timer.NewsIndex.cs

六  搜索优化:

搜索结果高亮显示:

搜索结果中 获取最匹配的摘要段,关键词需要高亮显示

引用 PanGu.HighLight.dll

 Front.FrontHelper.cs

 Front.News.NewsController.ashx

七  扩展任务:

项目任务:完成新闻搜索、视频笔记搜索功能,而且是综合搜索
逻辑思路://搜索(分页\高亮显示)-->建立索引-->出队列-->入队列T_Segment(Id,Name,note,ChapterId)\T_News(Id,Title,NewsContent,CategoryId)

 综合搜索:

 入队列:

 Admin/Course/CateogoryController.ashx?action=allSegmentIndex

 BLL/CourseBLL.cs

 出队列并写入索引 :

 Timer/NewsAndSegmentIndex.cs

 综合搜索:

 Front/News/NewsController.ashx?action=search

分类: NETRuPeng-DIDAO

时间: 2024-11-02 13:21:57

Lucene.Net 站内搜索的相关文章

Lucene.net站内搜索1——SEO优化简介

声明:在这里,所谈的一切关于SEO的技术主要针对于我们开发人员. SEO (搜索引擎优化) SEO(搜索引擎优化)的目的(很多人都是通过搜索引擎找到我们的网站)是让搜索引擎更多的收录网站的页面,让被收录页面的权重更靠前,让更多的人能够通过搜索引擎进入这个网站 原理:蜘蛛会定时抓取网站的内容,发现网站内容变化.发现新增内容就反映到搜索引擎中 蜘蛛(spider) 爬网站:就是向网站发http get请求的客户端. SEO(搜索引擎优化*):让网站排名靠前,让网站更多的页面被搜索引擎收录.链接(外链

Lucene.net站内搜索2—Lucene.Net简介和分词

Lucene.Net简介 Lucene.Net是由Java版本的Lucene(卢思银)移植过来的,所有的类.方法都几乎和Lucene一模一样,因此使用时参考Lucene 即可.Lucene.Net只是一个全文检索开发包(就像ADO.Net和管理系统的关系),不是一个成型的搜索引擎,它的功能就是:把数据扔给Lucene.Net ,查询数据的时候从Lucene.Net 查询数据,可以看做是提供了全文检索功能的一个数据库.SQLServer中和Lucene.Net各存一份,目的不一样.Lucene.N

Lucene.net站内搜索3—最简单搜索引擎代码

Lucene.Net核心类简介 先运行写好的索引的代码,再向下讲解各个类的作用,不用背代码. (*)Directory表示索引文件(Lucene.net用来保存用户扔过来的数据的地方)保存的地方,是抽象类,两个子类FSDirectory(文件中).RAMDirectory (内存中).使用的时候别和IO里的Directory弄混了. 创建FSDirectory的方法,FSDirectory directory =FSDirectory.Open(new DirectoryInfo(indexPa

基于lucene.net 和ICTCLAS2014的站内搜索的实现1

Lucene.net是一个搜索引擎的框架,它自身并不能实现搜索,需要我们自己在其中实现索引的建立,索引的查找.所有这些都是根据它自身提供的API来实现.Lucene.net本身是基于java的,但是经过翻译成.ne版本的,可以在ASP.net中使用这个来实现站内搜索. 要实现基于汉语的搜索引擎,首先的要实现汉语的分词.目前网上大部分都是利用已经有的盘古分词来实现的分词系统,但是盘古分词效果不太好.在这里我把最新的ICTCLAS2014嵌入到Lucene.net中.Lucene.net中所有的分词

基于lucene.net 和ICTCLAS2014的站内搜索的实现2

分词系统建立完毕,这是基础也是核心,后面我们建立索引要用到分词系统. 下面依次讲解索引的建立,索引的查找. 分词系统建立完毕,这是基础也是核心,后面我们建立索引要用到分词系统.下面依次讲解索引的建立,索引的查找. 索引的建立采用的是倒排序,原理就是遍历所有的文本,对其进行分词,然后把分的词汇建立索引表.形式类似如下: 词汇          出现词汇的篇章1,篇章2,篇章3-- 建立索引的时候要注意这样的Document,Field这俩术语.Document代表的是一个文档,它里面包含一个或者多

使用Lucene.NET实现站内搜索

使用Lucene.NET实现站内搜索 导入Lucene.NET 开发包 Lucene 是apache软件基金会一个开放源代码的全文检索引擎工具包,是一个全文检索引擎的架构,提供了完整的查询引擎和索引引擎,部分文本分析引擎.Lucene的目的是为软件开发人员提供一个简单易用的工具包,以方便的在目标系统中实现全文检索的功能,或者是以此为基础建立起完整的全文检索引擎.Lucene.Net 是 .NET 版的Lucene. 你可以在这里下载到最新的Lucene.NET 创建索引.更新索引.删除索引 搜索

B2C商城关键技术点总结(站内搜索、定时任务)

1.站内搜索 1.1Lucene.Net建立信息索引 1 string indexPath = @"E:\xxx\xxx";//索引保存路径 2 FSDirectory directory = FSDirectory.Open(new DirectoryInfo(indexPath), new NativeFSLockFactory()); 3 bool isUpdate = IndexReader.IndexExists(directory); 4 if (isUpdate) 5 {

一步步开发自己的博客 .NET版(5、Lucenne.Net 和 必应站内搜索)

前言 这次开发的博客主要功能或特点:    第一:可以兼容各终端,特别是手机端.    第二:到时会用到大量html5,炫啊.    第三:导入博客园的精华文章,并做分类.(不要封我)    第四:做个插件,任何网站上的技术文章都可以转发收藏 到本博客. 所以打算写个系类:<一步步搭建自己的博客> 一步步开发自己的博客  .NET版(1.页面布局.blog迁移.数据加载) 一步步开发自己的博客  .NET版(2.评论功能) 一步步开发自己的博客  .NET版(3.注册登录功能) 一步步开发自己

利用Solr服务建立的站内搜索雏形

最近看完nutch后总感觉像好好捯饬下solr,上次看到老大给我展现了下站内搜索我便久久不能忘怀.总觉着之前搭建的nutch配上solr还是有点呆板,在nutch爬取的时候就建立索引到solr服务下,然后在solr的管理界面中选择query,比如在q选项框中将"*:*"改写为"title:安徽",则在管理界面中就能看到搜索结果,可是这个与搜索引擎的感觉差远了,总感觉这些结果是被solr给套在他的管理界面中了,于是自己在网上搜索,也想整个站内搜索一样的东西,就算整不到