如何修改 SQL 2005 中的全文索引同义词库?

如何修改 SQL 2005 中的全文索引同义词库?

所以我读过这个: 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,我可以随时尝试它的同义词库功能,因为我相信它更好。在那之前,这将有效。

相关内容