lucene 分词.net盘古分词可是怎么也查不出来!scoredoc【】这个集合一直是空 的!

&&&&&& 各位朋友,谢谢大家的支持,由于文件过大,有考虑到版权的问题,故没有提供下载,本人已建立一个搜索技术交流群:,源代码已上传至群共享,需要的朋友,请自行下载!
& & & &首先自问自答几个问题,以让各位看官了解写此文的目的
什么是站内搜索?与一般搜索的区别?很多网站都有搜索功能,很多都是用SQL语句的Like实现的,但是Like无法做到模糊匹配(例如我搜索&.net学习&,如果有&.net的学习&,Like就无法搜索到,这明显不符合需求,但是站内搜索就能做到),另外Like会造成全盘扫描,会对数据库造成很大压力,为什么不用数据库全文检索,跟普通SQL一样,很傻瓜,灵活性不行
为什么不用百度、google的站内搜索?毕竟是别人的东西,用起来肯定会受制于人(哪天你的网站火了,它看你不爽了,就可能被K),主要还是索引的不够及时,网站新的内容,需要一定时间才能被索引到,并且用户的体验也不太好
& & & 最近改造了《动力起航》的站内搜索的功能,它其实已经有站内搜索的功能,但是是用like来实现的,改造此功能是本着在尽可能少的修改网站的源代码的情况下去改造此功能以及此站内搜索功能可以很好的移植到其他项目的原则来编写!本文有借鉴其他大神及园友的技术,在此谢谢!
站内搜索使用的技术Log4Net& 日志记录
lucene.Net&& 全文检索开发包,只能检索文本信息
分词(lucene.Net提供StandardAnalyzer一元分词,按照单个字进行分词,一个汉字一个词)
盘古分词&& 基于词库的分词,可以维护词库
& & & 首先我们新增的SearchHelper类需要将其做成一个单例,使用单例是因为:有许多地方需要使用使用,但我们同时又希望只有一个对象去操作,具体代码如下:
#region 创建单例
// 定义一个静态变量来保存类的实例
private static SearchHelper uniqueI
// 定义一个标识确保线程同步
private static readonly object locker = new object();
// 定义私有构造函数,使外界不能创建该类实例
private SearchHelper()
/// &summary&
/// 定义公有方法提供一个全局访问点,同时你也可以定义公有属性来提供全局访问点
/// &/summary&
/// &returns&&/returns&
public static SearchHelper GetInstance()
// 当第一个线程运行到这里时,此时会对locker对象 "加锁",
// 当第二个线程运行该方法时,首先检测到locker对象为"加锁"状态,该线程就会挂起等待第一个线程解锁
// lock语句运行完之后(即线程运行完之后)会对该对象"解锁"
lock (locker)
// 如果类的实例不存在则创建,否则直接返回
if (uniqueInstance == null)
uniqueInstance = new SearchHelper();
return uniqueI
#endregion
& & & & 其次,使用Lucene.Net需要将被搜索的进行索引,然后保存到索引库以便被搜索,我们引入了&生产者,消费者模式&. 生产者就是当我们新增,修改或删除的时候我们就需要将其在索引库进行相应的操作,我们将此操作交给另一个线程去处理,这个线程就是我们的消费者,使用&生产者,消费者模式&是因为:索引库使用前需解锁操作,使用完成之后必须解锁,所以只能有一个对象对索引库进行操作,避免数据混乱,所以要使用生产者,消费者模式
首先我们来看生产者,代码如下:
private Queue&IndexJob& jobs = new Queue&IndexJob&();
//任务队列,保存生产出来的任务和消费者使用,不使用list避免移除时数据混乱问题
/// &summary&
/// 任务类,包括任务的Id ,操作的类型
/// &/summary&
class IndexJob
public int Id { get; set; }
public JobType JobType { get; set; }
/// &summary&
/// 枚举,操作类型是增加还是删除
/// &/summary&
enum JobType { Add, Remove }
#region 任务添加
public void AddArticle(int artId)
IndexJob job = new IndexJob();
job.Id = artId;
job.JobType = JobType.A
logger.Debug(artId + "加入任务列表");
jobs.Enqueue(job);//把任务加入商品库
public void RemoveArticle(int artId)
IndexJob job = new IndexJob();
job.JobType = JobType.R
job.Id = artId;
logger.Debug(artId + "加入删除任务列表");
jobs.Enqueue(job);//把任务加入商品库
#endregion
下面是消费者,消费者我们单独一个线程来进行任务的处理:
/// &summary&
/// 索引任务线程
/// &/summary&
private void IndexOn()
logger.Debug("索引任务线程启动");
while (true)
if (jobs.Count &= 0)
Thread.Sleep(5 * 1000);
//创建索引目录
if (!System.IO.Directory.Exists(IndexDic))
System.IO.Directory.CreateDirectory(IndexDic);
FSDirectory directory = FSDirectory.Open(new DirectoryInfo(IndexDic), new NativeFSLockFactory());
bool isUpdate = IndexReader.IndexExists(directory);
logger.Debug("索引库存在状态" + isUpdate);
if (isUpdate)
//如果索引目录被锁定(比如索引过程中程序异常退出),则首先解锁
if (IndexWriter.IsLocked(directory))
logger.Debug("开始解锁索引库");
IndexWriter.Unlock(directory);
logger.Debug("解锁索引库完成");
IndexWriter writer = new IndexWriter(directory, new PanGuAnalyzer(), !isUpdate, Lucene.Net.Index.IndexWriter.MaxFieldLength.UNLIMITED);
ProcessJobs(writer);
writer.Close();
directory.Close();//不要忘了Close,否则索引结果搜不到
logger.Debug("全部索引完毕");
private void ProcessJobs(IndexWriter writer)
while (jobs.Count != 0)
IndexJob job = jobs.Dequeue();
writer.DeleteDocuments(new Term("number", job.Id.ToString()));
//如果&添加文章&任务再添加,
if (job.JobType == JobType.Add)
BLL.article bll = new BLL.article();
Model.article art = bll.GetArticleModel(job.Id);
if (art == null)//有可能刚添加就被删除了
string channel_id = art.channel_id.ToString();
string title = art.
DateTime time = art.add_
string content = Utils.DropHTML(art.content.ToString());
string Addtime = art.add_time.ToString("yyyy-MM-dd");
Document document = new Document();
//只有对需要全文检索的字段才ANALYZED
document.Add(new Field("number", job.Id.ToString(), Field.Store.YES, Field.Index.NOT_ANALYZED));
document.Add(new Field("title", title, Field.Store.YES, Field.Index.ANALYZED, Lucene.Net.Documents.Field.TermVector.WITH_POSITIONS_OFFSETS));
document.Add(new Field("channel_id", channel_id, Field.Store.YES, Field.Index.NOT_ANALYZED));
document.Add(new Field("Addtime", Addtime, Field.Store.YES, Field.Index.NOT_ANALYZED));
document.Add(new Field("content", content, Field.Store.YES, Field.Index.ANALYZED, Lucene.Net.Documents.Field.TermVector.WITH_POSITIONS_OFFSETS));
writer.AddDocument(document);
logger.Debug("索引" + job.Id + "完毕");
#endregion
以上我们就把索引库建立完毕了,接下来就是进行搜索了,搜索操作里面包括对搜索关键词进行分词,其次是搜索内容搜索词高亮显示,下面就是搜索的代码:
#region 从索引搜索结果
/// &summary&
/// 从索引搜索结果
/// &/summary&
public List&Model.article& SearchIndex(string Words, int PageSize, int PageIndex, out int _totalcount)
_totalcount = 0;
Dictionary&string, string& dic = new Dictionary&string, string&();
BooleanQuery bQuery = new BooleanQuery();
string title = string.E
string content = string.E
title = GetKeyWordsSplitBySpace(Words);
QueryParser parse = new QueryParser(Lucene.Net.Util.Version.LUCENE_29, "title", new PanGuAnalyzer());
Query query = parse.Parse(title);
parse.SetDefaultOperator(QueryParser.Operator.AND);
bQuery.Add(query, BooleanClause.Occur.SHOULD);
dic.Add("title", Words);
content = GetKeyWordsSplitBySpace(Words);
QueryParser parseC = new QueryParser(Lucene.Net.Util.Version.LUCENE_29, "content", new PanGuAnalyzer());
Query queryC = parseC.Parse(content);
parseC.SetDefaultOperator(QueryParser.Operator.AND);
bQuery.Add(queryC, BooleanClause.Occur.SHOULD);
dic.Add("content", Words);
if (bQuery != null && bQuery.GetClauses().Length & 0)
return GetSearchResult(bQuery, dic, PageSize, PageIndex, out _totalcount);
return null;
/// &summary&
/// &/summary&
/// &param name="bQuery"&&/param&
private List&Model.article& GetSearchResult(BooleanQuery bQuery, Dictionary&string, string& dicKeywords, int PageSize, int PageIndex, out int totalCount)
List&Model.article& list = new List&Model.article&();
FSDirectory directory = FSDirectory.Open(new DirectoryInfo(IndexDic), new NoLockFactory());
IndexReader reader = IndexReader.Open(directory, true);
IndexSearcher searcher = new IndexSearcher(reader);
TopScoreDocCollector collector = TopScoreDocCollector.create(1000, true);
Sort sort = new Sort(new SortField("Addtime", SortField.DOC, true));
searcher.Search(bQuery, null, collector);
totalCount = collector.GetTotalHits();//返回总条数
TopDocs docs = searcher.Search(bQuery, (Filter)null, PageSize * PageIndex, sort);
if (docs != null && docs.totalHits & 0)
for (int i = 0; i & docs.totalH i++)
if (i &= (PageIndex - 1) * PageSize && i & PageIndex * PageSize)
Document doc = searcher.Doc(docs.scoreDocs[i].doc);
Model.article model = new Model.article()
id = int.Parse(doc.Get("number").ToString()),
title = doc.Get("title").ToString(),
content = doc.Get("content").ToString(),
add_time = DateTime.Parse(doc.Get("Addtime").ToString()),
channel_id = int.Parse(doc.Get("channel_id").ToString())
list.Add(SetHighlighter(dicKeywords, model));
/// &summary&
/// 设置关键字高亮
/// &/summary&
/// &param name="dicKeywords"&关键字列表&/param&
/// &param name="model"&返回的数据模型&/param&
/// &returns&&/returns&
private Model.article SetHighlighter(Dictionary&string, string& dicKeywords, Model.article model)
SimpleHTMLFormatter simpleHTMLFormatter = new PanGu.HighLight.SimpleHTMLFormatter("&font color=\"red\"&", "&/font&");
Highlighter highlighter = new PanGu.HighLight.Highlighter(simpleHTMLFormatter, new Segment());
highlighter.FragmentSize = 250;
string strTitle = string.E
string strContent = string.E
dicKeywords.TryGetValue("title", out strTitle);
dicKeywords.TryGetValue("content", out strContent);
if (!string.IsNullOrEmpty(strTitle))
string title = model.
model.title = highlighter.GetBestFragment(strTitle, model.title);
if (string.IsNullOrEmpty(model.title))
model.title =
if (!string.IsNullOrEmpty(strContent))
string content = model.
model.content = highlighter.GetBestFragment(strContent, model.content);
if (string.IsNullOrEmpty(model.content))
model.content =
/// &summary&
/// 处理关键字为索引格式
/// &/summary&
/// &param name="keywords"&&/param&
/// &returns&&/returns&
private string GetKeyWordsSplitBySpace(string keywords)
PanGuTokenizer ktTokenizer = new PanGuTokenizer();
StringBuilder result = new StringBuilder();
ICollection&WordInfo& words = ktTokenizer.SegmentToWordInfos(keywords);
foreach (WordInfo word in words)
if (word == null)
result.AppendFormat("{0}^{1}.0 ", word.Word, (int)Math.Pow(3, word.Rank));
return result.ToString().Trim();
#endregion
以上我们的站内搜索的SearchHelper类就建立好了,下面来讲讲如何使用,此类提供以下几个方法对外使用:
在Global里面启动消费者线程:
protected void Application_Start(object sender, EventArgs e)
//启动索引库的扫描线程(生产者)
SearchHelper.GetInstance().CustomerStart();
在需被搜索的新增或修改处添加下面方法:
SearchHelper.GetInstance().AddArticle(model.id);
在需被搜索的删除处添加下面方法:
SearchHelper.GetInstance().RemoveArticle(model.id);
搜索的时候使用下面的方法即可:
public List&Model.article& SearchIndex(string Words, int PageSize, int PageIndex, out int _totalcount)
& & & &以上就是整个站内搜索的全部代码,SearchHelper帮助类下载地址:
& & & &本来想直接提供改造了《动力起航》的源代码,这样就可以直接看到效果了,一方面由于文件过大,另一方面不知道是不是会侵权,所有没有提供下载.如果有需要的朋友可以留下邮箱我将发给你,但仅供学习交流之用,误用做商业用途,以上如果有侵权等问题还请及时告知我,以便我及时更正!
& & & &很荣幸此文能上最多推荐,多谢大家的支持,由于索要改造了《动力起航》的源代码的园友很多,一一发给大家有点麻烦,在考虑是否放到网盘提供大家下载是不是更方便一些,但是不知道这样会不会有侵权之嫌啊,求各位给个建议,如果可以我就上传网盘了,不行的话就只能一个一个发给大家了!
& & & &最好如果觉得好的话!请给个推荐啊~~~~亲!!!!
阅读(...) 评论()相关文章推荐
Q:站内搜索为什么不能使用Like模糊查找
A:模糊契合度太低,匹配关键字之间不能含有其他内容。最重要的是它会造成全表扫描,效率底下,即使使用视图,也会造成数据库服务器"亚历山大"
.NET中文分词实现http://http://使用Lucene.Net.dll http://www.apache.org/dist/incubator/lucene.net/binaries/2....
Lucene.Net只是一个全文检索开发包。它的功能就是提供了全文检索功能的一个数据库。Lucene.Net不管文本数据怎么来的,用户可以基于Lucene.Net开发满足自己需求的搜索引擎。Lucen...
Lucene.Net只是一个全文检索开发包。它的功能就是提供了全文检索功能的一个数据库。Lucene.Net不管文本数据怎么来的,用户可以基于Lucene.Net开发满足自己需求的搜索引擎。Lucen...
这几天完成一个相关lucene.net 索引,特此写上来供大爱评论!建立全文索引,主要有两步,一,建立索引,二,查找,那么我先来讲一下怎么新建索引!引用类:Imports System.DataImp...
本章阅读概要
1、Lucenne.Net简介
2、介绍盘古分词器
3、Lucene.Net实例分析
4、结束语(Demo下载)
Lucene.Net简介
  Luc...
string[] GetInfo ={ keyword, keyword, keyword };
string[] Info ={ "title", "description"...
各位朋友,谢谢大家的支持,由于文件过大,有考虑到版权的问题,故没有提供下载,本人已建立一个搜索技术交流群:,源代码已上传至群共享,需要的朋友,请自行下载!
using System.Collections.G
using System.L
using Syst...
转自:http://blog.csdn.net/pukuimin1226/article/details/
[csharp] view plaincopyp...
他的最新文章
他的热门文章
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)Q:站内搜索为什么不能使用Like模糊查找A:模糊契合度太低,匹配关键字之间不能含有其他内容。最重要的是它会造成全表扫描,效率底下,即使使用视图,也会造成数据库服务器"亚历山大"Lucene简介:Lucene.Net只是一个全文检索开发包,不是一个成型的搜索引擎它提供了类似SQLServer数据库正式版中的全文检索功能的索引库你把数据扔给Lucene.Net,【Lucene.Net只针对文本信息建立索引,所以他只接收文本信息,如果不是文本信息,则要转换为文本信息】它会将文本内容分词后保存在索引库中,当用户输入关键字提交查询时,Lucene.Net从索引库中检索关键字数据,所以搜索速度非常快,适合于用户开发自己站内的搜索引擎Q:分词A:即将"不是所有痞子都叫一毛"文本内容通过分词算法 &分割成为&不是& &所有& &痞子& &都& &叫& "一毛" &。 但是Lucene.Net内置分词算法对中文支持不是很好,以下会使用国内较为流行的分词算法 -- 盘古分词以下是运行图解:下面以用户查询数据库Book表 & 内容描述【对应字段名:ContentDescription】中包含其输入的关键字key的数据 &演示Lucene.Net使用运行界面效果如下:&本人使用的盘古分词版本为V2.3.1.0& Lucene.Net为2.9在项目下新建Dict文件以及dll文件包含Lucene与盘古分词所需的组件及文件信息如图示1、项目添加对dll文件夹中四个程序集的引用2、添加图书搜索页面SearchBlogs.aspx代码如下:&%&@&Page&Language="C#"&AutoEventWireup="true"&CodeBehind="SearchBook.aspx.cs"&Inherits&="BookShop.Web.SearchBook"&%&&!&DOCTYPE&html&PUBLIC&"-//W3C//DTD XHTML 1.0 Transitional//EN"&"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&&&html&="http://www.w3.org/1999/xhtml"&&&head&runat&="server"&&&&&&title&&&/&title&&/&head&&&body&&&&&&form&id="form1"&runat="server"&&&&&&asp&:&TextBox&ID&="txtSerach"&runat&="server"&Width&="494px"&&/asp&:&TextBox&&&&&&asp&:&Button&ID&="btnSearch"&runat&="server"&onclick&="btnSearch_Click"&Text&="搜索"&/&&&&&&asp&:&Button&ID&="CreateView"&runat&="server"&onclick&="CreateView_Click"&Text&="创建索引"&/&&&&&&div&&&&&&&&&&&&asp:&Repeater&ID&="Repeater1"&runat&="server"&&&&&&&&&&&ItemTemplate&&&&&&&&&&&table&&&&&&&&&&&&&&&&&&&tbody&&&&&&&&&&&&&&&&&&&&&&&tr&&&&&&&&&&&&&&&&&&&&&&&&&&&td&style&="font-size&:&color: red"&width="650"&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&a&&id&="link_prd_name"&href&='&%&#&Eval("Id","/book.aspx?id={0}")&%&&'&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&target&="_blank"&name&="link_prd_name"&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&%#&Eval(&"Title")&%&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&/&a&&&&&&&&&&&&&&&&&&&&&&&&&&/&td&&&&&&&&&&&&&&&&&&&&&&/&tr&&&&&&&&&&&&&&&&&&&&&&&tr&&&&&&&&&&&&&&&&&&&&&&&&&&&td&align&="left"&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&span&style&="font-size&: 12&line-height: 20px"&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&%#&Eval(&"ContentDescription")&%&&/&span&&&&&&&&&&&&&&&&&&&&&&&&&&&/&td&&&&&&&&&&&&&&&&&&&&&&/&tr&&&&&&&&&&&&&&&&&&/&tbody&&&&&&&&&&&&&&/&table&&&&&&&&&&/&ItemTemplate&&&&&&&&&&/&asp:&Repeater&&&&&&&/div&&&&&&&/form&&&/&body&&/&html&3、后台调用using&Susing&System.Collections.Gusing&System.IO;using&BookShop.BLL;using&Lucene.Net.Analysis.PanGu;using&Lucene.Net.Dusing&Lucene.Net.Iusing&Lucene.Net.Susing&Lucene.Net.Snamespace&BookShop.Web {&&&&public&partial&class&SearchBook&: System.Web.UI.&Page&{&&&&&&&&protected&void&Page_Load(&object&sender,&EventArgs&e) {&&&&&&& }& & & &&//创建索引事件& 可以防止在用户点击查询事件前执行 去掉页面中的"创建索引"按钮&&&&&&&&protected&void&CreateView_Click(&object&sender,&EventArgs&e) {&&&&&&&&&&&&string&indexPath =&@"C:\luceneTest"&;&//索引文档保存位置&&&&&&&&&&&&FSDirectory&directory =&FSDirectory&.Open(&new&DirectoryInfo&(indexPath),&new&NativeFSLockFactory&());&&&&&&&&&&&&bool&isUpdate =&IndexReader&.IndexExists(directory);&//是否存在索引库文件夹以及索引库特征文件&&&&&&&&&&&&if&(isUpdate) {&&&&&&&&&&&&&&&&//如果索引目录被锁定(比如索引过程中程序异常退出或另一进程在操作),则解锁&&&&&&&&&&&&&&&&if&(IndexWriter&.IsLocked(directory)) {&&&&&&&&&&&&&&&&&&&&IndexWriter&.Unlock(directory);&&&&&&&&&&&&&&& }&&&&&&&&&&& }&&&&&&&&&&&&//创建索引库对象&& new PanGuAnalyzer()指定使用盘古分词进行切词&&&&&&&&&&&&IndexWriter&writer =&new&IndexWriter(directory,&new&PanGuAnalyzer&(), !isUpdate, Lucene.Net.Index.IndexWriter&.&MaxFieldLength.UNLIMITED);&&&&&&&&&&&&BooksManager&bookManager =&new&BooksManager();&&&&&&&&&&&&List&&Model.Books&& bookList = bookManager.GetModelList(&""&);&&&&&&&&&&&&foreach&(var&book&in&bookList) {&&&&&&&&&&&&&&&&Document&document =&new&Document();&//new 一篇文档 对象&&&&&&&&&&&&&&&&//所有字段的值都将以字符串类型保存&&&&&&&&&&&&&&&&//Field.Store表示是否保存字段原值。指定Field.Store.YE的字段在检索时才能用document.Get取出来值& NOT_ANALYZED指定不按照分词后的结果保存&&&&&&&&&&&&&&& document.Add(&new&Field&(&"id", book.Id.ToString(),&Field&.Store&.YES,&Field&.Index&.NOT_ANALYZED));&&&&&&&&&&&&&&& document.Add(&new&Field&(&"title", book.Title,&Field&.Store&.YES,&Field&.Index&.ANALYZED, Lucene.Net.Documents.Field&.TermVector&.WITH_POSITIONS_OFFSETS));&&&&&&&&&&&&&&&&//Field.Index. ANALYZED指定文章内容按照分词后结果保存& 否则无法实现后续的模糊查找& WITH_POSITIONS_OFFSETS指示不仅保存分割后的词 还保存词之间的距离&&&&&&&&&&&&&&& document.Add(&new&Field&(&"content", book.ContentDescription,&Field&.Store&.YES,&Field.&Index&.ANALYZED, Lucene.Net.Documents.Field&.TermVector&.WITH_POSITIONS_OFFSETS));&&&&&&&&&&&&&&& writer.AddDocument(document);&//文档写入索引库&&&&&&&&&&& }&&&&&&&&&&& writer.Close();&&&&&&&&&&& directory.Close();&//不要忘了Close,否则索引结果搜不到&&&&&&& }&&&&&&&&protected&void&btnSearch_Click(&object&sender,&EventArgs&e) {&&&&&&&&&&&&string&indexPath =&@"C:\luceneTest"&;&&&&&&&&&&&&FSDirectory&directory =&FSDirectory&.Open(&new&DirectoryInfo&(indexPath),&new&NoLockFactory&());&&&&&&&&&&&&IndexReader&reader =&IndexReader&.Open(directory,&true);&&&&&&&&&&&&IndexSearcher&searcher =&new&IndexSearcher(reader);&//Index:索引&&&&&&&&&&&&//搜索条件&&&&&&&&&&&&PhraseQuery&query =&new&PhraseQuery();&&&&&&&&&&&&//把用户输入的关键字进行分词&&&&&&&&&&&&foreach&(string&word&in&Common.SplitContent&.SplitWords(txtSerach.Text.ToLower())) {&&&&&&&&&&&&&&& query.Add(&new&Term&(&"content", word));&&&&&&&&&&& }&&&&&&&&&&& query.SetSlop(100);&//指定关键词相隔最大距离&&&&&&&&&&&&//TopScoreDocCollector盛放查询结果的容器&&&&&&&&&&&&TopScoreDocCollector&collector =&TopScoreDocCollector&.create(1000,&true&);&&&&&&&&&&& searcher.Search(query,&null&, collector);//根据query查询条件进行查询,查询结果放入collector容器&&&&&&&&&&&&//TopDocs 指定0到GetTotalHits() 即所有查询结果中的文档&&&&&&&&&&&&ScoreDoc&[] docs = collector.TopDocs(0, collector.GetTotalHits()).scoreD&&&&&&&&&&&&//展示数据实体对象集合&&&&&&&&&&&&List&&Model.Books&& bookResult =&new&List&&Model.Books&&();&&&&&&&&&&&&for&(int&i = 0; i & docs.L i++) {&&&&&&&&&&&&&&&&//需要获得文档的详细内容的时候通过searcher.Doc来根据文档id来获得文档的详细内容对象Document&&&&&&&&&&&&&&&&int&docId = docs[i].//得到查询结果文档的id(Lucene内部分配的id)&&&&&&&&&&&&&&&&Document&doc = searcher.Doc(docId);//找到文档id对应的文档详细信息&&&&&&&&&&&&&&& Model.&Books&book =&new&Model.&Books();&&&&&&&&&&&&&&& book.Title = doc.Get(&"title"&);&&&&&&&&&&&&&&&&//book.ContentDescription = doc.Get("content");//未使用高亮&&&&&&&&&&&&&&&&//搜索关键字高亮显示&&&&&&&&&&&&&&& book.ContentDescription = Common.SplitContent&.HightLight(txtSerach.Text, doc.Get("content"&));&&&&&&&&&&&&&&& book.Id =&Convert&.ToInt32(doc.Get("id"&));&&&&&&&&&&&&&&& bookResult.Add(book);&&&&&&&&&&& }&&&&&&&&&&&&//设置Repeater1& 绑定查询结果集合&&&&&&&&&&& Repeater1.DataSource = bookR&&&&&&&&&&& Repeater1.DataBind();&&&&&&& }&&& }}4、使用到的公共类 Common下的SplitContent类using&System.Collections.Gusing&System.IO;using&Lucene.Net.Ausing&Lucene.Net.Analysis.PanGu;using&PanGu;namespace&mon {&&&&public&class&SplitContent&{&&&&&&&&public&static&string[] SplitWords(&string&content) {&&&&&&&&&&&&List&&string&& strList =&new&List&&string&&();&&&&&&&&&&&&Analyzer&analyzer =&new&PanGuAnalyzer();&&&&&&&&&&&&TokenStream&tokenStream = analyzer.TokenStream(""&,&new&StringReader&(content));&&&&&&&&&&& Lucene.Net.Analysis.&Token&token =&null&;&&&&&&&&&&&&while&((token = tokenStream.Next()) !=&null&) {&//Next继续分词 直至返回null&&&&&&&&&&&&&&& strList.Add(token.TermText());&//得到分词后结果&&&&&&&&&&& }&&&&&&&&&&&&return&strList.ToArray();&&&&&&& }&&&&&&&&//需要添加PanGu.HighLight.dll的引用&&&&&&&&///&&summary&&&&&&&&&///&搜索结果高亮显示&&&&&&&&///&&/summary&&&&&&&&&///&&param name="keyword"&&关键字&&/param&&&&&&&&&///&&param name="content"&&搜索结果&&/param&&&&&&&&&///&&returns&&高亮后结果&&/returns&&&&&&&&&public&static&string&HightLight(&string&keyword,&string&content) {&&&&&&&&&&&&//创建HTMLFormatter,参数为高亮单词的前后缀&&&&&&&&&&& PanGu.HighLight.&SimpleHTMLFormatter&simpleHTMLFormatter =&&&&&&&&&&&&&&&&&&&new&PanGu.HighLight.SimpleHTMLFormatter&(&"&font color=\"red\"&&b&",&"&/b&&/font&"&);&&&&&&&&&&&&//创建 Highlighter ,输入HTMLFormatter 和 盘古分词对象Semgent&&&&&&&&&&& PanGu.HighLight.&Highlighter&highlighter =&&&&&&&&&&&&&&&&&&&&&&&&&&&&new&PanGu.HighLight.Highlighter&(simpleHTMLFormatter,&&&&&&&&&&&&&&&&&&&&&&&&&&&&new&Segment&());&&&&&&&&&&&&//设置每个摘要段的字符数&&&&&&&&&&& highlighter.FragmentSize = 50;&&&&&&&&&&&&//获取最匹配的摘要段&&&&&&&&&&&&return&highlighter.GetBestFragment(keyword, content);&&&&&&& }&&& }}5、使用Dict、Dll文件夹以及盘古分词的开发文档点击下载&&&&&&& 实际应用中当然不会存在上图中的创建索引按钮& 而且索引需随数据库数据同步更新&& 本章暂不介绍
、 、 、 、 、 、

我要回帖

更多关于 lucene 中文分词器 的文章

 

随机推荐