技术开发 频道

DNN中搜索引擎原理:如何获取SearchItem

ITPUB 技术文档】DNN是如和将形式各异的模块内容提取到SearchItem表中的呢?SearchWord(索引关键字)表的内容又是如何获得呢?

   首先,模块实现ISearchable接口是解决以上问题的基础。在DNN中定义了一个ISearchable接口(ISearchable.vb文件中),该接口中的GetSearchItems方法就提供了获取查询条目的途径。模块通过实现ISearchable接口的GetSearchItems 方法,并以SearchItemInfoCollection形式返回自身内容的查询条目集合。这样就使千变万化的模块内容统一成一种形式的 SearchItem。以大家最熟悉的Text/HTML模块为例,以下是它实现ISearchable接口的方法:
 

' 实现ISearchable接口
Public Function GetSearchItems()Function GetSearchItems(ByVal ModInfo As Entities.Modules.ModuleInfo) As Services.Search.SearchItemInfoCollection Implements Entities.Modules.ISearchable.GetSearchItems

Dim SearchItemCollection As New SearchItemInfoCollection

Dim HtmlText As HtmlTextInfo = GetHtmlText(ModInfo.ModuleID)

If Not HtmlText Is Nothing Then
'DesktopHTML is encoded in the Database so Decode before Indexing
Dim strDesktopHtml As String = HttpUtility.HtmlDecode(HtmlText.DeskTopHTML)

'Get the description string,获取描述字符串
Dim strDescription As String = HtmlUtils.Shorten(HtmlUtils.Clean(strDesktopHtml, False), MAX_DESCRIPTION_LENGTH, "")
'构造了一个查询条目对象
Dim SearchItem As SearchItemInfo = New SearchItemInfo(ModInfo.ModuleTitle, strDescription, HtmlText.CreatedByUser, HtmlText.CreatedDate, ModInfo.ModuleID, "", strDesktopHtml, "", Null.NullInteger)
SearchItemCollection.Add(SearchItem)
End If
Return SearchItemCollection

End Function


   其中SearchItemInfo类中Content属性是关键,它决定了可以被检索到的内容,如果不能很好的给出这个属性的内容就不能得到预期的查询效果。比如Links模块,它提供的查询条目的Content属性是链接的描述信息。很多人在添加链接时都没有写描述信息,那么这个链接就会搜索不到,如果用链接的“标题+描述信息”作为Content属性的内容就很好了。另外,需要强调一点:没有实现ISearchable接口的模块内容是不能被检索到的。

   知道各个模块是如何提供查询条目的了,那么DNN是如何来收集这些条目信息的呢?DNN收集这些条目信息的方法有两种:
   1、通过调度(Schedule)的方式,定期自动收集查询条目。在“主机管理->调度管理”中可看见相关的调度信息。
   2、通过重建索引,手动收集。在“主机管理->搜索管理”。

   这也就是说,如果刚刚添加的内容是不能马上每检索到,只有重建索引后才能。无论哪种方法,它们都将调用SearchEngine类中的IndexContent()方法。顺着这条线走下去,大家就会明白,内容太多就不详细写了。

   值得一提的是两个抽象的Provider,利用反射的原理动态的创建web.config中设置的默认用到的子类:(是一个反射工厂模式)
   1、IndexingProvider:检索制定站点可以被查询到的内容,具体的实现类是ModuleIndexer(ModuleIndexer.vb)
   2、SearchDataStoreProvider:向数据库中存/取制定的查询内容,具体的实现类是SearchDataStore(SearchDataStore.vb)
   程序架构上来看编写新的Provider子类应该可以改进查询的方式,具体如何操作没有想到。

   DNN中的搜索功能对中文不是很有效,主要是出在获取索引关键字上。在SearchDataStore类中的AddIndexWords方法中可以看出,关键字是由查询条目中Content属性的内容用空格分割开来的。老外的文章里面空格随处可以,可是我们的文章中空格就不那么多了。总不能要求大家每输入一个词就空一格吧。如果连续超过100字都没有空格,那么这段文字就不能被作为索引关键字,即便是用like '%' + @Word+'%'的临时解决方案也无法查出。临时解决方案在《DNN中搜索引擎原理——数据库分析篇》提到过,这是一种牺牲性能换结果的方法,因为用like '%%'将不能使用索引,其效果还是全表搜索,当SearchWord表中内容很多的时候是会有很大的性能差异的。

   另外大家还可以看看CanIndexWord方法,它用来判断一个单词是否可以做为关键字。常用字(如:a,can等)、数字、过长单词、过短单词这些都可以设置为不能作为关键字。具体设置可在“主机管理->搜索管理”中进行。

 

0
相关文章