所以我读过这个: http://www.simple-talk.com/sql/learn-sql-server/understanding-full-text-indexing-in-sql-server/
我对 tsENU.xml 文件做了以下修改,以包含“程序员”和“编程”同义词:
<XML ID="Microsoft Search Thesaurus">
<thesaurus xmlns="x-schema:tsSchema.xml">
<diacritics_sensitive>0</diacritics_sensitive>
<expansion>
<sub>Internet Explorer</sub>
<sub>IE</sub>
<sub>IE5</sub>
</expansion>
<replacement>
<pat>NT5</pat>
<pat>W2K</pat>
<sub>Windows 2000</sub>
</replacement>
<expansion>
<sub>run</sub>
<sub>jog</sub>
</expansion>
<expansion>
<sub>programmer</sub>
<sub>programming</sub>
</expansion>
</thesaurus>
</XML>
最后一步,我重新启动了全文索引服务。
我读到的所有内容似乎都表明这就是我应该做的全部。但遗憾的是,它并没有像我预期的那样影响搜索结果。在我的数据库中搜索“编程”会返回 59 个结果,而“程序员”只返回 1 个。我预计结果数量相同,因此我认为服务器实际上并没有更新同义词库。
有任何想法吗?
答案1
所以我放弃了这个服务器问题,而是用代码来解决它。
这不是我心目中的理想解决方案,但我花了大约一个小时就完成了我自己的同义词库功能。这比我研究这个主题所花的时间还短。
这是我编写的 VB.NET 函数:
Public Shared Function GetFullTextSearch(ByVal strSearch As String) As String
If strSearch > "" Then
strSearch = Regex.Replace(strSearch, "\s\s+", " ").Trim.ToLower
strSearch = Regex.Replace(strSearch, "[^\w\s]", "")
Dim arrKeywords() As String = strSearch.Split(" ")
Dim strFullTextSearch As String = ""
Dim xpathDoc As XPathDocument
Dim xmlNav As XPathNavigator
Dim xmlNI As XPathNodeIterator
Try
xpathDoc = New XPathDocument(Current.Server.MapPath("~\bin\FullTextSynonyms.xml"))
xmlNav = xpathDoc.CreateNavigator()
Catch ex As Exception
Current.Trace.Warn(ex.ToString)
End Try
For Each strKeyword As String In arrKeywords
If strFullTextSearch > "" Then
strFullTextSearch &= " AND "
End If
If Not xpathDoc Is Nothing Then
xmlNI = xmlNav.Select("/Thesaurus/Synonyms[Synonym='" & strKeyword & "']/Synonym")
If xmlNI.Count > 0 Then
Dim strSearchOr As String = ""
While xmlNI.MoveNext()
If strSearchOr > "" Then
strSearchOr &= " OR "
End If
strSearchOr &= "FORMSOF(INFLECTIONAL, '" & xmlNI.Current.Value & "')"
End While
If strSearchOr > "" Then
strFullTextSearch &= "(" & strSearchOr & ")"
End If
Else
strFullTextSearch &= "FORMSOF(INFLECTIONAL, '" & strKeyword & "')"
End If
End If
Next
Return strFullTextSearch
Else
Return Nothing
End If
End Function
以及相应的自定义同义词库文件:
<?xml version="1.0" encoding="utf-8" ?>
<Thesaurus>
<Synonyms>
<Synonym>program</Synonym>
<Synonym>programmer</Synonym>
<Synonym>programming</Synonym>
</Synonyms>
<Synonyms>
<Synonym>consult</Synonym>
<Synonym>consultant</Synonym>
<Synonym>consulting</Synonym>
</Synonyms>
<Synonyms>
<Synonym>web</Synonym>
<Synonym>website</Synonym>
</Synonyms>
</Thesaurus>
实际上,这会产生比必要更多的处理,因为在某些情况下,我在类似的术语上多次使用 FORMSOF 函数。
例如,当用户搜索“web consultant”时,这是传递到 CONTAINSTABLE 函数的实际全文搜索:
(FORMSOF(INFLECTIONAL, 'web') OR FORMSOF(INFLECTIONAL, 'website')) AND (FORMSOF(INFLECTIONAL, 'consult') OR FORMSOF(INFLECTIONAL, 'consultant') OR FORMSOF(INFLECTIONAL, 'consulting'))
当然,这不是性能最好的解决方案,但它对我们的数据库来说仍然非常快,而且从功能上来说,这正是我所寻找的。此外,我现在能够修改我的自定义同义词库文件,而无需重新启动全文索引服务。但是,如果我们稍后升级到 SQL 2008,我可以随时尝试它的同义词库功能,因为我相信它更好。在那之前,这将有效。