DNN中搜索引擎原理

来源:百度文库 编辑:神马文学网 时间:2024/04/29 03:29:20
DNN中搜索引擎原理——数据库分析篇
Posted on 2005-08-15 17:50二十四画生 阅读(3927)评论(11)  编辑  收藏 所属分类:DotNetNuke(DNN)
DotNetNuke(以下简称DNN)中所采取的搜索方式,并不是我们通常所想象的直接再要查询的表中直接搜索。因为DNN中的模块是多种多样的,各数据表的形式和要查询的字段也是不一样,如果直接查询每一个表的内容是几乎不可能实现的。DNN中引入了一个SearchItem表,将各种各样的需要查询的内容,归结为查询条目的形式添加到该表中。同时还引出了一个SearchWord表,将需要查询的内容分解成一个个关键字,这样更能加快检索速度,而且还利于多关键字检索。在DNN搜索中还有一个小技巧:可以通过“key1 key2”的形式进行多关键字检索,并且可以通过“key1+ key2-”形式明确指出是否必须保含某关键字,是否必须排除某关键字。整个和搜索相关表的关系图如下:

从关系图上来看,只要在SearchWord表中找到指定关键字,通过SearchItemWord表,就能知道要查询的内容了。通过SearchItem表,就能确切知道是哪个模块了。
各表个字段的详细解释:
SearchCommonWords:★常用字/词组信息表(存储指定文化区域的常用字,在查询时输入这些字是不会返回结果的)
字段名
类型
含义
备注
CommonWordID
Int
常用字ID
主键
CommonWord
Nvarchar(255)
常用字
如:where,about在英文中都属于常用字
Locale
Nvarchar(10)
所属文化区域
SearchIndexer:★索引Provider的程序集(这个表的数据好像没有用,在web.config中有设置)
字段名
类型
含义
备注
SearchIndexerID
Int
ID
主键
SearchIndexerAssemblyQualifiedName
Char(200)
程序集
SearchItem:★模块内容搜索条目(将所有可能被搜索到的模块内容,通过定时调度的方式,将模块内容以搜索条目的形式保存,这样可加快搜索速度)
字段名
类型
含义
备注
SearchItemID
Int
搜索条目ID
主键
Title
Nvarchar(200)
标题
Description
Nvarchar(2000)
描述
Author
Int
作者Id
PubDate
Datetime
发布日期
ModuleId
Int
所属模块Id
与模块信息表(Modules)关联
SearchKey
Nvarchar(100)
搜索关键字
Guid
Varchar(200)
好像是指示模块中的一条记录
HitCount
Int
点击次数
ImageFileId
Int
SearchItemWord:★搜索关键字索引信息表(搜索条目和搜索关键字之间的关系)
字段名
类型
含义
备注
SearchItemWordID
Int
搜索关键字索引ID
主键
SearchItemID
Int
搜索条目Id
关联模块内容搜索条目表(SearchItem)
SearchWordsID
Int
搜索关键字Id
关联搜索关键字信息表(SearchWordsID)
Occurrences
Int
出现次数
关键字在指定搜索内容中的出现次数
SearchItemWordPosition:★搜索关键字在被搜索内容中出现的位置
字段名
类型
含义
备注
SearchItemWordPositionID
Int
ID
主键
SearchItemWordID
Int
搜索关键字索引ID
关联搜索关键字索引信息表(SearchItemWord)
ContentPosition
Int
出现位置
SearchWord:★搜索关键字信息表(存储可供检索的关键字)
字段名
类型
含义
备注
SearchWordsID
Int
搜索关键字ID
主键
Word
Nvarchar(100)
搜索关键字
IsCommon
Bit
是否是常用字
HitCount
Int
点击次数
一个可以改进的存储过程:
查看获取查询结果的存储过程GetSearchResults,我们会发现必须完全匹配查找关键字才能查出所需的内容。问题就在“sw.Word = @Word”这一句上,也就是说如果一个模块中包含“DotNetNuke”这个内容,那么他输入“Nuke”是不会查出来的。将这一句改成“sw.Word  like '%' + @Word+'%'”就可以了(这是一个以效率换结果的方法)。具体修改方法见:http://www.cnblogs.com/esshs/archive/2005/08/12/213154.html
从数据表和所实现的功能上看,某些表的数据字段还没有用上,估计是DNN预留字段以便日后扩充。看完这篇文章的不知大家对DNN的查询功能是否有一个大概的了解。以后将继续针对如何通过各功能模块所实现的查询接口来填充SearchItem表;点击“查询”是如何工作的这些方面的问题来继续说明DNN搜索引擎原理。上文有任何讲解不正确的地方还请大家指出,以免误导他人。
更多相关内容>>
Feedback
# re: DNN中搜索引擎原理——数据库分析篇   回复  引用  查看  
2005-08-15 20:52 by
使用LIKE就不能利用索引了吧……
# re: DNN中搜索引擎原理——数据库分析篇   回复  引用  查看  
2005-08-15 21:05 by二十四画生
@commenter
不是很清楚你这句话的意思。
# re: DNN中搜索引擎原理——数据库分析篇   回复  引用  查看  
2005-08-15 21:45 by
我想大概这个是分词表吧,跟.lucene一样,需要先进行分词,然后索引,以加快检索的速度
# re: DNN中搜索引擎原理——数据库分析篇   回复  引用  查看  
2005-08-15 23:26 by小残
@二十四画生
commenter 的索引应该是指全文索引
# re: DNN中搜索引擎原理——数据库分析篇   回复  引用  查看  
2005-08-16 05:04 by大厨师
讨论一下
http://www.cnblogs.com/henry_zjk/archive/2005/03/23/123843.html
# re: 关于dotnetnuke中文搜索问题的分析+临时方法 2005-03-24 08:51奋斗中的灵感之源
%中文%是全表搜索,索引根本用不上,很低效率,用低效率换结果,不值得:(
# re: DNN中搜索引擎原理——数据库分析篇   回复  引用  查看  
2005-08-16 08:47 by二十四画生
如何从中文中提取关键字,看来是解决问题的关键。不过好多人都喜欢用模糊搜索,即便是英文方式,也有人不愿意输入整个单词进行检索。有谁清楚Google和百度是如何做的吗?
# re: DNN中搜索引擎原理——数据库分析篇   回复  引用  查看  
2005-08-16 09:43 by
ASPNET FORUMS也是采用这种方式。
我只能说:这种搜索的方法是弊大于利。我已经将原来的ASPNET FORUMS的这种关键字搜索已经改成了用DotLucene开源项目引擎搜索。
# re: DNN中搜索引擎原理——数据库分析篇   回复  引用  查看  
2005-08-16 10:08 by
有几个分词引擎
海量智能分词组件
www.vgoogle.net 也有一个
不过都不是免费的
# re: DNN中搜索引擎原理——数据库分析篇   回复  引用  查看  
2005-08-19 17:25 by
这个有没有c#版本的?
# re: DNN中搜索引擎原理——数据库分析篇   回复  引用  查看  
2006-01-09 21:01 by二十四画生
改进DNN的SearchProviders,加入中文词库,用中文词库来提取分词,这样能行吗?
# re: DNN中搜索引擎原理——数据库分析篇   回复  引用  查看  
2006-09-08 14:03 by期望
全文索引能弥补这个缺陷
DNN中搜索引擎原理——如何获取SearchItem
Posted on 2005-08-18 16:27二十四画生 阅读(2303)评论(3)  编辑  收藏 所属分类:DotNetNuke(DNN)
上一篇《DNN中搜索引擎原理——数据库分析篇》讲到DotNetNuke(以下简称DNN)是将各模块的内容以SearchItem(查询条目)的形式存储到数据库中供检索,并通过索引关键字来加快对查询条目的检索。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表中内容很多的时候是会有很大的性能差异的。
以上问题在这篇文章中也有提到:http://www.cnblogs.com/henry_zjk/archive/2005/03/23/123843.html
另外大家还可以看看CanIndexWord方法,它用来判断一个单词是否可以做为关键字。常用字(如:a,can等)、数字、过长单词、过短单词这些都可以设置为不能作为关键字。具体设置可在“主机管理->搜索管理”中进行。
本来还想画几幅UML图的,怎奈这方面的水平有限(以后加强学习),画出来怕反到误导了大家。不知本文说清楚了没有,如有错误或遗漏之出还望大家指出,以免误导他人。
更多相关内容>>
Feedback
# re: DNN中搜索引擎原理——如何获取SearchItem   回复  引用  查看  
2005-08-18 17:24 bychengulv
我们自己开发的模块只要实现了 ISearchable接口 就可以被DNN搜索到吗?
那比如我做了个文章管理系统, DNN搜索到文章标题,那我怎么让标题有个指到具体内容的超链接?
# re: DNN中搜索引擎原理——如何获取SearchItem   回复  引用  查看  
2005-08-18 17:46 by二十四画生
@chengulv
只要开发的模块实现了ISearchable接口,就可以被DNN搜索到。至于“DNN搜索到文章标题,那我怎么让标题有个指到具体内容的超链接?”这个问题完全不用你操心,DNN帮你做了。你可以看看searchresults模块,它里面的内容解释了你要问得问题。我也将再写篇文章说明DNN是如何获取搜索结果、是如何展现出来的。
# re: DNN中搜索引擎原理——如何获取SearchItem   回复  引用  查看  
2007-02-03 12:46 by李生
5000万条数据,300G(MSSQL格式)
要求搜索返回时间不超过1秒
如何实现?请教请教!!!
QQ:271937025