lucene.net 盘古分词词 函数求值需要运行所有线程

很强大的开源的分词库
秒后自动跳转到登录页
(奖励5下载豆)
快捷登录:
举报类型:
不规范:上传重复资源
不规范:标题与实际内容不符
不规范:资源无法下载或使用
其他不规范行为
违规:资源涉及侵权
违规:含有危害国家安全等内容
违规:含有反动/色情等内容
违规:广告内容
详细原因:
任何违反下载中心规定的资源,欢迎Down友监督举报,第一举报人可获5-10下载豆奖励。
Edraw2014亿图图示专
全国省市县无刷新多
SOA 治理:框架和最
单页网站制作第一课
一个SSH框架开发的完
W3School离线手册(2
购物商城系统(仿京
很强大的开源的分词库
上传时间:
技术分类:
资源评价:
(2位用户参与评价)
已被下载&117&次
按词性分词,按词组分词,有强大的词库,按词性分词,按词组分词,有强大的词
本资料共包含以下附件:
很强大的开源的分词库.rar
51CTO下载中心常见问题:
1.如何获得下载豆?
1)上传资料
2)评论资料
3)每天在首页签到领取
4)购买VIP会员服务,无需下载豆下载资源
5)更多途径:点击此处
2.如何删除自己的资料?
下载资料意味着您已同意遵守以下协议:
1.资料的所有权益归上传用户所有
2.未经权益所有人同意,不得将资料中的内容挪作商业或盈利用途
3.51CTO下载中心仅提供资料交流平台,并不对任何资料负责
4.本站资料中如有侵权或不适当内容,请邮件与我们联系()
5.本站不保证资源的准确性、安全性和完整性, 同时也不承担用户因使用这些资料对自己和他人造成任何形式的伤害或损失
下载1014次
下载1290次
下载1149次
下载1101次
下载1219次
下载1285次
相关专题推荐
PHP是在服务器端执行的嵌入HTML文档的
本教程循序渐进,由浅及深;具有完整
PHP是一种HTML内嵌式的语言,是一种在
本专题为XML视频教程,共20集,视频格
ExtJS是一种主要用于创建前端用户界面
您想不想设计出漂亮美观的网页?这专
本视频教程有针对性的讲解Ajax技术如
本专题包含了Java Web开发必须的各种
JSP技术使用Java编程语言编写类XML的
本专题为UML实战操作视频教程,讲解了
小甲鱼版delphi视频学习,从入门到精
主要讲述springMVC启用注解功能,还有
这是韩顺平老师最新版的jsp视频教程
韩顺平.第二版XML视频教程.共21讲,本
Flex 是一个高效、免费的开源框架,可
ERP是英文Enterprise Resource Plann
本周下载热点
意见或建议:
联系方式:
您已提交成功!感谢您的宝贵意见,我们会尽快处理盘古分词使用手册_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
评价文档:
盘古分词使用手册
上传于||文档简介
&&盘​古​分​词​器​使​用​手​册
大小:456.20KB
登录百度文库,专享文档复制特权,财富值每天免费拿!
你可能喜欢public string fenci(string text)
string textFc = string.E
Analyzer anal = new PanGuAnalyzer();
StringReader sb = new StringReader(text);
TokenStream ts = anal.ReusableTokenStream("", sb);
while ((t = ts.Next()) != null)
textFc += t.TermText() + " ";
return textFc;
}能直接获得这个吗
--------------------------------------
有没有人阿,
--------------------------------------
貌似会分开
--------------------------------------
TokenStream ts看看这个ts的方法有没有直接返回分词组成的字符串&&&&&& 各位朋友,谢谢大家的支持,由于文件过大,有考虑到版权的问题,故没有提供下载,本人已建立一个搜索技术交流群:,源代码已上传至群共享,需要的朋友,请自行下载!
& & & &首先自问自答几个问题,以让各位看官了解写此文的目的
什么是站内搜索?与一般搜索的区别?很多网站都有搜索功能,很多都是用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帮助类下载地址:
& & & &本来想直接提供改造了《动力起航》的源代码,这样就可以直接看到效果了,一方面由于文件过大,另一方面不知道是不是会侵权,所有没有提供下载.如果有需要的朋友可以留下邮箱我将发给你,但仅供学习交流之用,误用做商业用途,以上如果有侵权等问题还请及时告知我,以便我及时更正!
& & & &很荣幸此文能上最多推荐,多谢大家的支持,由于索要改造了《动力起航》的源代码的园友很多,一一发给大家有点麻烦,在考虑是否放到网盘提供大家下载是不是更方便一些,但是不知道这样会不会有侵权之嫌啊,求各位给个建议,如果可以我就上传网盘了,不行的话就只能一个一个发给大家了!
& & & &最好如果觉得好的话!请给个推荐啊~~~~亲!!!!
阅读(...) 评论()漓筝轩:一个人的江湖 | 盘古分词DotNet版本的修改
我是Jeason Zhao,我在这里,默默的存在,活得像空气
盘古分词DotNet版本的修改
17:24:49 |
我原本就是懒人,何尝勤快过,懒散了这么多年,对一个库是否好用,除了功能满足之外,还有就是简单,最好是简单的一塌糊涂,连傻瓜都会——话说傻瓜也能当程序员了,没活路了。
Lucene本身是很不错的,不管插件机制还是代码效率,都很不错,但是毕竟有些不大不小的水土不服,例如中文分词这个领域就比较麻烦,虽然可以使用标准分词的结构,但是大家都晓得“武汉市长江大桥欢迎您”的闹剧,不是偶然,而是必然,中文的上下文和语境在特定的环境下会产生变化,例如上例,从技术角度来看,没有一点错误。
最后我选择了DotNet版本的盘古分词作为中文分词的引擎。我现在没有在JAVA下面做开发,不知道有没有JAVA版本。
盘古分词本身的发布中包含了字典数据,但是字典数据是在体外加载的,也就是说需要新建目录并配置XML文件指定这个目录。这使得使用盘古分词的客户程序必须引入字典才能运行,而且,如果没有这些文件,会爆出异常信息。对于我这样的人,我希望能在一个DLL中全部都搞定。所以这次对盘古进行了一点点改造,在segment工程中增加了字典数据作为嵌入资源,初始化的时候将资源自动读取出来然后生成目录和文件。这样,一个DLL就可以搞定全部东西了。
关键代码:
using System.Collections.G
using System.T
using System.R
using System.IO;
namespace PanGu
//This class has been integrated into Commons.Utils, for reduce dependencies,
//I add a duplicate copy in this package. Please don't use it widly.
internal class ResourceExtractor
public static void Init()
lock (typeof(ResourceExtractor))
System.Console.WriteLine(typeof(ResourceExtractor).FullName + &...&);
string path = GetDictionaryPath();
if (System.IO.Directory.Exists(path)
&& System.IO.File.bine(path, &Dict.dct&)))
System.Console.WriteLine(typeof(ResourceExtractor).FullName + &.SKIP&);
Directory.CreateDirectory(path);
Type type = typeof(ResourceExtractor);
Assembly asm = type.A
//foreach (string strResourceName in asm.GetManifestResourceNames())
System.Console.WriteLine(strResourceName);
string namespaceP=&PanGu.PanGuDictionaries.&;
string[] files=new string[]{&Stopword.txt&
,&Synonym.txt&
,&ChsSingleName.txt&
,&Dict.dct&
,&ChsDoubleName1.txt&
,&ChsDoubleName2.txt&
,&Wildcard.txt&};
foreach (string f in files)
WriteResourceStreamToFile(type, asm, bine(path, f), namespaceP + f);
catch(Exception ex)
System.Console.WriteLine(ex.Message);
System.Console.WriteLine(ex.StackTrace);
System.Console.WriteLine(typeof(ResourceExtractor).FullName + &.DONE&);
public static string GetDictionaryPath()
string path = PanGu.Setting.PanGuSettings.DefaultDictionaryP
string currentDir = System.IO.Directory.GetCurrentDirectory();
System.IO.Directory.SetCurrentDirectory(Framework.Path.GetAssemblyPath());
path = System.IO.Path.GetFullPath(path);
System.IO.Directory.SetCurrentDirectory(currentDir);
return PanGu.Framework.Path.AppendDivision(path, '\\');
private static void WriteResourceStreamToFile(Type type
, Assembly asm, string fileName, string strResourceName)
string strFoldername = (new FileInfo(fileName)).Directory.FullN
if (Directory.Exists(strFoldername) == false)
Directory.CreateDirectory(strFoldername);
if (File.Exists(fileName))
File.Delete(fileName);
FileStream fs = new FileStream(fileName, FileMode.OpenOrCreate, FileAccess.Write,FileShare.Read);
Stream src = asm.GetManifestResourceStream(strResourceName);
if (null == src)
int nLength = 32 * 1024;
byte[] buf = new byte[nLength];
int nx = 0;
while ((nx = src.Read(buf, 0, nLength)) & 0)
fs.Write(buf, 0, nx);
fs.Flush();
fs.Close();
src.Close();
src.Dispose();
昨晚迅猛的入睡,很奇怪的梦到大量的野生动物,瀑布汗一个,到底咋回事,难道某个在另外的时空的我溜到热带雨林去玩去了——哪位看到,请给我留言。

我要回帖

更多关于 盘古分词使用手册 的文章

 

随机推荐