关于dotnetnuke中文搜索问题的分析+临时方法
写这篇随笔主要是提出问题,问题我没有能力解决
关心dotnetnuek的很多朋友,都在关注着她
但是在不断的为dnn3的一步步成长感到欣慰的同时,也发现目前其距离我们中文用户的需求还相距很远。
很显著,也是最然人头疼得问题是:中文搜索,
一直以来使用中文关键字搜索都没有结果,或者仅有很少的结果
我开始发现了这个问题,但是并没有太关心,直到现在3.0.12出来,问题依然存在,因为3.0.12已经不是bata了,随后的3.0.13马上就会推出,官方根本就没有考虑中文搜索的问题
那么,为什么英文搜索可以中文搜索就不可以呢?
仔细看一下就发现的dotnetnuke搜索功能是使用SearchProviders来进行的,而SearchDataStore择为搜索提供关键词方面的功能,那么问题一定出在这里
作为测试,我首先在自己的dnn站点里添加了一些中文的内容,然后使用host下的搜索管理重建索引,重新打开SearchWord表,发现已经有中文内容添加了进来,但是作为关键词/可搜索内容的word却不是我们需要的,比如“中文搜索如何处理”“增加内容”“中文搜索听说有问题”“测试一下”,这些都是我为了测试输入的中文语句,而与此同时输入的英文内容却很正常,"chinese" "test" ,输入引号中的内容可以得出搜索结果,这样可以基本判断,问题出现在产生关键词的步骤,而向SearchWord表中添加内容的存储过程是AddSearchWord,那么是谁调用了AddSearchWord?最终错误定位在
SearchDataStore.vb的117行
L116~L134
Dim ContentWords() As String = Split(Content, " ")
' process each word
Dim intWord As Integer
Dim strWord As String
For Each strWord In ContentWords
If CanIndexWord(strWord, Language) Then
intWord = intWord + 1
If IndexWords.ContainsKey(strWord) = False Then
IndexWords.Add(strWord, 0)
IndexPositions.Add(strWord, 1)
End If
' track number of occurrences of word in content
IndexWords(strWord) = CType(IndexWords(strWord), Integer) + 1
' track positions of word in content
IndexPositions(strWord) = CType(IndexPositions(strWord), String) & "," & intWord.ToString
End If
Next
要想解决这个问题,可能的思路是
1、进行中文的分词,对中文或者中英文混合的内容进行索引
2、开发新的SearchProvider
以上均是浅见,不确切、不正确的地方,还请大家指教
按宝玉的指教,使用临时方法,用like查询
输入中文关键字的时候使用 %中文%
另外在host->SQL中执行如下代码
@PortalID int,
@Word nVarChar(100)
AS
SELECT si.SearchItemID,
sw.Word,
siw.Occurrences,
siw.Occurrences + 1000 as Relevance,
m.ModuleID,
tm.TabID,
si.Title,
si.Description,
si.Author,
si.PubDate,
si.SearchKey,
si.Guid,
si.ImageFileId,
u.FirstName + ' ' + u.LastName As AuthorName
FROM SearchWord sw
INNER JOIN SearchItemWord siw ON sw.SearchWordsID = siw.SearchWordsID
INNER JOIN SearchItem si ON siw.SearchItemID = si.SearchItemID
INNER JOIN Modules m ON si.ModuleId = m.ModuleID
LEFT OUTER JOIN TabModules tm ON si.ModuleId = tm.ModuleID
INNER JOIN Tabs t ON tm.TabID = t.TabID
LEFT OUTER JOIN Users u ON si.Author = u.UserID
WHERE
(((m.StartDate Is Null) OR (GetDate() > m.StartDate)) AND ((m.EndDate Is Null) OR (GetDate() < m.EndDate)))
AND (((t.StartDate Is Null) OR (GetDate() > t.StartDate)) AND ((t.EndDate Is Null) OR (GetDate() < t.EndDate)))
AND (sw.Word like @Word)
AND (t.IsDeleted = 0)
AND (m.IsDeleted = 0)
AND (t.PortalID = @PortalID)