Итак, я прочитал это: 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. Я ожидал бы того же количества результатов, поэтому я предполагаю, что сервер на самом деле не обновляет тезаурус.
Любые идеи?
Поэтому я отказался от этой проблемы с сервером и решил вместо этого с помощью кода.
Это не мое представление об идеальном решении, но я создал свой собственный тезаурус примерно за час. И это меньше времени, чем я потратил на изучение этой темы.
Это функция 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 несколько раз на аналогичных условиях.
Например, когда пользователь ищет «веб-консультант», это фактический полнотекстовый поиск, который передается в функцию CONTAINSTABLE:
(FORMSOF(INFLECTIONAL, 'web') OR FORMSOF(INFLECTIONAL, 'website')) AND (FORMSOF(INFLECTIONAL, 'consult') OR FORMSOF(INFLECTIONAL, 'consultant') OR FORMSOF(INFLECTIONAL, 'consulting'))
Конечно, это не самое производительное решение, но оно по-прежнему очень быстрое с нашей базой данных и функционально именно то, что я искал. Кроме того, теперь у меня есть возможность изменять свой собственный файл тезауруса без необходимости перезапуска службы полнотекстового индексирования. Но послушайте, если мы обновимся до SQL 2008 позже, я всегда могу попробовать его функциональность тезауруса, поскольку я считаю, что это лучше. А пока это будет работать.