前面几节里有朋友提到CS2对中文搜索支持的不好,那么这一节就提前到这里来讲讲怎样解决CS2对中文搜索的问题。
我们都知道,英文和中文语言上的不同导致了处理英文和中文的不同方法,最明显的不同就是英文是以单词为最小单位,而中文则是以字为最小单位,这样造成了程序上的不一样,而在CS2中默认的搜索模块只考虑到英文这一方面,对中文相当于不认识了,怎样让其认识中文呢,这就需要我们来分析CS2处理搜索的机制。
虽然CS2中使用的分词搜索,但其技术本身并不是很复杂,我们完全可以自己动手来改造其搜索效果。简单一点我就直截了当的介绍其分词搜索的原理吧。与我们常见的一些使用SQL语句在数据结构里搜索不同,分词搜索把需要搜索的数据预先进行索引(这里的索引不是通常所指的数据库本身的索引),在搜索引擎里的文章最小单位是词,英文按照单词,也就是按空格分开,中文就需要用到分词技术了,把一篇文章智能的分成多个词语的组合的技术,这也是搜索技术的核心,搜索结果的理想程度很大程度取决于分词的理想程度,把一篇文章分开为词语的组合后,将其内容逐个记录并保存权重值,当然这里也涉及到一些高级技术,在CS中使用了较简单的方式,直接记录词在其文章中的信息。搜索文章的时候在此即可快速定位到需要的文章。说了这么多感觉比较抽象,还是结合实例来说吧。
打开解决方案我们会看到有CommunityServerSearchBarrel这样的项目,在这个项目里都是一些job和Item形式的类,这些类就是完成索引的关键类,针对不同应用都有不同的job,说到Job,在之前的系列已经介绍过其工作方式就是在后台单独的进程里运行的组件,在CommunityServer.config的jobs节点里可以对这些Job进行配置,我们可以在这里配置索引的间隔时间。其原理即为,当到了设定的时间间隔,针对不同应用的SearchJob在后台独立的线程开始工作,先判断是否出现了未进行索引的文章如果有新的文章出现则读取出来进行索引(一般为几十条数据),索引完后进行记录,下次就不再重复进行了,直到文章被修改后再次进行。
简单了解了这么多之后让我们来解决问题吧,CS2不支持中文究竟问题出在哪里呢,让我们打开数据库的cs_SearchBarrel表,我们可以看到这里就是保存分词结果的地方,不过可以看到正确的一个个英文单词却很难看到一个正确的中文词语,这就是为什么CS2对中文支持的这么不好了,CS2在搜索时是检索这个表的数据的,这个表数据有问题当然就没有办法检索到正确的信息了。好了,现在已经很明确了,我们就是需要修改CS2对中文的分词,分词是一个复杂的技术,我们可以利用现有的分词组件来帮助我们。
博客园真是个好地方,在正需要分词组件的时候Eunge兄就发布了免费版本(虽然没开放源码,不过能用就行,何必太叫真呢),真是及时雨啊,无论分词效果怎样,这总归是个解决方案,我试用了它的组件,感觉还不错,能胜任一般的应用了,于是就拿了过来,发布网址参见:http://lovinger2000.cnblogs.com/archive/2006/03/02/ChineseTokenizerDll.HTML 那到这个好东东之后就可以开始我们的改造了:
那么我们应该如何改造呢,对,把系统分词的方法替换成中文组件的方法即可,那么怎样嵌入我们的中文分词组件呢,当然是顺潮流使用代理模式了,这样如果我们有更好的分词组件扩展起来是非常容易的。首先来看看CommunityServerSearchBarrel这个项目,这个项目就是处理搜索相关的地方。找到核心的调用让我们看看SearchJob.cs的Index方法,这个方面就是索引文章的方法了,在这里我们可以看到string[] wordsToIndex = SearchTerms.CleanSearchTerms(contentToIndex);这样的语句,不难理解,这个就是把文档的各部分转换为词的字符串数组了。SearchTerms.CleanSearchTerms这个方法在CommunityServerComponents项目的Search/SearchTerms.cs下,在这里就是要修改的核心了,我们可以看到其中都是对英文单词的处理,当然,我们只要替换掉对英文的处理为中文分词原则上就可以,主要的修改为:
CleanSearchTerms
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->
publicstaticstring[]CleanSearchTerms(stringsearchTerms)
{
if(searchTerms==null)
returnnewstring[0];
//ForcethesearchTermstolowercase
//
searchTerms=searchTerms.ToLower();
try
{
//Stripanymarkupcharacters
//
searchTerms=Transforms.StripHTMLXMLTags(searchTerms).Replace(" ","");
//Removenon-alpha/numericcharacters
//Editbylf没必要去掉特殊字符,有些时候仍然需要搜索它
//searchTerms=Regex.Replace(searchTerms,"[^\\w]","",RegexOptions.Compiled|RegexOptions.Multiline);
//Replacespecialwordswithsymbols
/**/////Editbylf这几句要出错
//searchTerms=Regex.Replace(searchTerms,"\\bor\\b","||",RegexOptions.Compiled|RegexOptions.Multiline);
//searchTerms=Regex.Replace(searchTerms,"\\band\\b","&&",RegexOptions.Compiled|RegexOptions.Multiline);
//Finallyremoveanyextraspacesfromthestring
//空格也不需要替换,中文分词自动替换
//searchTerms=Regex.Replace(searchTerms,"{1,}","",RegexOptions.IgnoreCase|RegexOptions.Compiled|RegexOptions.Multiline);
}
catch(System.Exceptionex)
{
try
{
CSExceptioncsEx=newCSException(CSExceptionType.SearchUnknownError,"中文分词异常,这个是在替换特殊字符的时候的异常",ex);
csEx.Log();
}
catch
{}
}
if(searchTerms.Trim()!=string.Empty)
{
//Editbylf设置为中文搜索
try
{returnChineseTokenizeProvider.Instance().ChineseTokenize(searchTerms);}
catch(System.Exceptionex)
{
try
{
CSExceptioncsEx=newCSException(CSExceptionType.SearchUnknownError,"中文分词异常",ex);
csEx.Log();
}
catch
{}
}
}
returnsearchTerms.Split('');
}
怎样引入我们的分词组件呢,让我们先建立一个抽象的Provider来作为代理的基础类,在这里建立名为ChineseTokenizeProvider,当然是在CommunityServerComponents项目里建立了。代码如下:
ChineseTokenizeProvider
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Text;
usingCommunityServer.Components;
usingCommunityServer.Configuration;
namespaceCommunityServer.Components
{
/**////<summary>
///中文分词的支持
///</summary>
///<remarks>Editbylf</remarks>
publicabstractclassChineseTokenizeProvider
{
Instance#regionInstance
privatestaticChineseTokenizeProvider_defaultInstance=null;
staticChineseTokenizeProvider()
{
CreateDefaultCommonProvider();
}
publicstaticChineseTokenizeProviderInstance()
{
return_defaultInstance;
}
privatestaticvoidCreateDefaultCommonProvider()
{
CSConfigurationconfig=CSConfiguration.GetConfig();
ProviderchineseProviders=(Provider)config.Providers["ChineseTokenizeProvider"];
_defaultInstance=Activator.CreateInstance(Type.GetType(chineseProviders.Type))asChineseTokenizeProvider;
}
#endregion
publicabstractstring[]ChineseTokenize(stringinput);
}//class
}
代码沿袭了CS中处理数据提供者的方式,只是这里使用的是分词提供方法,建立了基类后让我们建立一个扩展的代理层吧,这里我命名为Felix.NET.ChineseTokenWraper的项目其实就一个方法,也就是重写继承基类的抽象函数。如下:
Felix.NET.ChineseTokenWraper
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Text;
usingCommunityServer.Components;
usingSj110.Com.Chinese;
namespaceFelix.NET.ChineseTokenWraper
{
publicclassChineseTokenizer:ChineseTokenizeProvider
{
ChineseTokenizeProvider成员#regionChineseTokenizeProvider成员
publicoverridestring[]ChineseTokenize(stringinput)
{
List<string>resultList=Tokenizer.Tokenize(input);
string[]mystring=newstring[resultList.Count];
resultList.CopyTo(mystring);
returnmystring;
}
#endregion
}
}
当然完成了这些后还需要在配置文件加上这个Provider的配置,打开CommunityServer.config文件,在Providers配置节里添加如下代码:
<!--Editbylf加入对中文分词的支持-->
<add
name="ChineseTokenizeProvider"
type="Felix.NET.ChineseTokenWraper.ChineseTokenizer,Felix.NET.ChineseTokenWraper"
/>
处理完这些后就可以说大功告成了一半了,只是还有很多语言方面的问题需要我们在调试的时候处理,具体的处理细节我就不细说了,自己调试调试就ok了,我也放上自己的CommunityServerSearchBarrel项目,主要修改也就是这个项目了。
发现写这个文档怎么这么费力,好像还没说得很清楚,不过实在精力有限,还有很多事情等着我做,要完善这个功能还需要你细心调试,这里也就起到引个路子的作用,如果它能帮到你,我花这些功夫就没白费了。
源代码下载(修正了本文一个遗漏点,即2字词的索引,英文对于3个字母不处理)
这个方法是我测试过,可以使用的,并且效果不错,可以到 http://bbs.cnfdc.com.cn 测试。
点这里直接测试
不过修正后需要将cs_posts表的isindexed字段置为0,还有cs_sections表issearchable字段置为1,然后删除cs_SearchBarrel里面的所有记录。重起cs,过15分钟后,cs就开始建立索引了,这个时候你打开cs_SearchBarrel表,如果看到的都是汉字单词,那么就恭喜你,成功了。根据你的帖子量,很快你的搜索结果就很可观了。
补充:改进cs搜索结果的高亮显示
首先保证你的中文搜索按照上面的说明修改成功,然后打开Skin-SearchResults.ascx,修改下面这段
<atarget="_blank"href="<%#DataBinder.Eval(Container.DataItem,"Url")%>"><%...#Formatter.GetBodySummary(DataBinder.Eval(Container.DataItem,"BestMatch").ToString(),350,earchTextTop.Text,System.Drawing.Color.Black,System.Drawing.Color.Yellow)%></a>
为
<atarget="_blank"href="<%#DataBinder.Eval(Container.DataItem,"Url")%>"><%...#Formatter.GetBodySummary(DataBinder.Eval(Container.DataItem,"BestMatch").ToString(),350,ChineseTokenizeProvider.Instance().ChineseTokenize(SearchTextTop.Text),System.Drawing.Color.Black,System.Drawing.Color.Yellow)%></a>
然后修改\Components\Components\Formatter.cs里面的
public static string GetBodySummary(string text, int size, string[] highlightWords, Color color, Color bgColor)
方法,不知道官方的想法,这里对于字符串数组高亮的显示处理不能理解,修改为
publicstaticstringGetBodySummary(stringtext,intsize,string[]highlightWords,Colorcolor,ColorbgColor)
...{
//EAD6/27/04:NewfunctionIwroteamonthagotostripall
//tagsoutandreplacewithlinebreaks.Inthiscase,weneedto
//insert<br/>sinplaceoflinebreakssoitlookssomewhatneat.
//
//LN6/23/04:DonotHtmlencodethebody
//postBody=Globals.HtmlEncode(Transforms.StripHtmlXmlTags(postBody));
//postBody=Transforms.StripHtmlXmlTags(postBody);
stringpostBody=Formatter.StripAllTags(text);
//Weonlywanttodisplaysomeofthebody
//
if(size>0&&postBody.Length>size)
...{
intwhitespace=0;
//Clipthebody
postBody=postBody.Substring(0,size);
//Findthelastoccurenceofaspace
whitespace=postBody.LastIndexOf("");
if(whitespace==-1)
whitespace=size;
//RebuildpostBodystring
postBody=postBody.Substring(0,whitespace)+"...";
}
//Doanywordhighlighting
//
if(highlightWords.Length>0)
...{
//注释:王勇,修改高亮显示,支持中文分词
//stringdelimitedString;
/**/////Splitanddelimitstring
////
//delimitedString=Transforms.ToDelimitedString(highlightWords,"|");
/**/////TDD7/19/2004
////thisstringisusedastheregexpattern.ifitcontainsspecialcharacterslike(,*$it
////throwanerrorsincethesearespecialinstructioncharacterstoRegex.Wemustescapethese
////specialcharactersiftheyareusedassearchstrings.
//delimitedString=Regex.Escape(delimitedString);
/**/////Performreplacement
////
foreach(stringdelimitedStringinhighlightWords)
...{
postBody=Regex.Replace(postBody,delimitedString,"<spanstyle="color:"+color.Name+";background-color:"+bgColor.Name+""><b>$0</b></span>",RegexOptions.IgnoreCase|RegexOptions.Compiled|RegexOptions.Multiline);
}
}
returnpostBody;
}
重新编译,测试,OK,这样你的cs就可以自动按照分词来高亮每一个关键字了。
分享到:
相关推荐
美国马里兰大学电池测试数据集(CALCE Battery Research Group),需要的自取。由于文件大小限制,将文件数据集分为七个部分。 数据集1:https://download.csdn.net/download/CSDN_zss0/16744619 数据集2:...
《中文版Illustrator CS2实用教程》是一款专为学习Adobe Illustrator CS2设计的教程资源,旨在帮助用户掌握这款强大的矢量图形设计软件的基础操作和高级技巧。Illustrator CS2是Adobe公司推出的图形设计软件,广泛...
美国马里兰大学电池测试数据集(CALCE Battery Research Group),需要的自取。由于文件大小限制,将文件数据集分为七个部分。 数据集1:https://download.csdn.net/download/CSDN_zss0/16744619 数据集2:...
美国马里兰大学电池测试数据集(CALCE Battery Research Group),需要的自取。由于文件大小限制,将文件数据集分为七个部分。 数据集1:https://download.csdn.net/download/CSDN_zss0/16744619 数据集2:...
标题中的"BCM94360CS2-win7/8/10驱动"指的是博通(Broadcom)公司生产的BCM94360CS2无线网络和蓝牙适配器的驱动程序,适用于Windows 7、8和10操作系统。这款驱动程序是连接计算机到Wi-Fi网络和蓝牙设备的关键组件。 ...
本资源“photoshop CS2试题汇编素材和效果第4单元”显然是一个专门针对学习和测试Photoshop CS2技能的资料包,主要涵盖了第4单元的学习内容。下面将详细解析这一单元可能包含的知识点。 1. **基本操作**:这部分...
对于下载了绿色版的photoshop的用户,请运行此补丁。 运行:Photoshop CS2 [9.0] 注册表补丁
在这个案例中,"对人像相片进行处理,效果非常棒,同样推荐"可能是指一个预设的动作文件,包含了上述人像处理的整个流程,用户只需加载并运行这个动作,就能得到理想的人像效果。 6. **色彩理论与调色**:理解色彩...
这个中文版Photoshop CS2实用教程课件将详细讲解以上各个知识点,并通过实例教学帮助用户提升技能,无论你是初学者还是有一定基础的用户,都能从中受益。通过学习,你将能够熟练运用Photoshop CS2进行图像创作和编辑...
Photoshop CS2是一款由Adobe公司推出的经典图像处理软件,它在设计、摄影、艺术创作等领域具有广泛的应用。这款软件以其强大的功能和灵活的操作性深受专业设计师和业余爱好者的喜爱。"photoshop cs2素材"指的是适用...
Photoshop CS2中文版是一款由Adobe公司开发的专业图像处理软件,是数字图像编辑与创作的行业标准。本教程聚焦于其在实际应用中的技巧和方法,尤其关注如何利用素材进行有效的图像编辑和设计工作。教程内容包括但不...
6. **文字工具**:Photoshop CS2支持添加和编辑文本,创建引人注目的文字效果,包括文本路径、文本变形等功能。 7. **图层样式与混合模式**:图层样式如阴影、发光、描边等能快速为图像添加视觉效果。混合模式则...
### PHOTOSHOP CS2 快捷键大全详解 #### 一、概述 Photoshop CS2作为Adobe公司出品的一款强大的图像处理软件,在设计领域占据着举足轻重的地位。为了提高工作效率,掌握Photoshop CS2中的快捷键尤为重要。本文将...
根据提供的信息,我们可以总结出以下有关“名师李涛老师主讲 Photoshop CS2”的知识点: ### 一、课程介绍 名师李涛老师的《Photoshop CS2》教程,是针对Adobe公司的图像处理软件Photoshop CS2的专业培训课程。该...
Adobe Illustrator CS2 SDK 是一套由Adobe公司推出的软件开发工具包,专为Windows操作系统设计,用于帮助开发者和程序员创建、扩展或集成与Adobe Illustrator CS2版本兼容的插件和应用程序。这个SDK提供了必要的文档...
Photoshop CS2是一款由Adobe公司推出的图像处理软件,它在设计、艺术创作和照片编辑领域具有广泛的应用。本实例精选教程电子书旨在帮助用户通过实际操作掌握Photoshop CS2的各项功能,提升图像编辑技巧。 教程内容...
2. **图层管理**:如同Photoshop,ImageReady CS2支持图层操作,用户可以在不同的图层上独立工作,方便地进行图像组合和效果调整。 3. **切割工具**:对于网页设计师来说,切割工具是非常有用的。它可以将一个大的...
Photoshop CS2是一款由Adobe公司推出的经典图像处理软件,它在设计、摄影、艺术创作等领域具有广泛的应用。作为一款强大的图片处理工具,Photoshop CS2提供了丰富的功能,包括图像编辑、修复、合成、调色、滤镜应用...
【标题】"CS2中文手册(已编译的HTML文件)"所指的"CS"很可能是"计算机科学"(Computer Science)或者"CSS"(层叠样式表,Cascading Style Sheets)的缩写。根据描述和标签,这里更倾向于指的是CSS,即网页设计中的...