Expandindo a ideia de Ismael, não é a solução final, mas acho que é uma boa maneira de começar.
Em primeiro lugar, precisamos obter a lista de palavras que foram recuperadas com o mecanismo de texto completo:
declare @SearchPattern nvarchar(1000) = 'FORMSOF (INFLECTIONAL, " ' + @SearchString + ' ")'
declare @SearchWords table (Word varchar(100), Expansion_type int)
insert into @SearchWords
select distinct display_term, expansion_type
from sys.dm_fts_parser(@SearchPattern, 1033, 0, 0)
where special_term = 'Exact Match'
Já há muito que se pode expandir, por exemplo, o padrão de pesquisa é bastante básico; provavelmente também há maneiras melhores de filtrar as palavras que você não precisa, mas pelo menos fornece uma lista de palavras-tronco etc. que seriam correspondidas pela pesquisa de texto completo.
Depois de obter os resultados necessários, você pode usar o RegEx para analisar o conjunto de resultados (ou, de preferência, apenas um subconjunto para acelerá-lo, embora eu ainda não tenha descoberto uma boa maneira de fazê-lo). Para isso eu simplesmente uso dois loops while e um monte de tabelas e variáveis temporárias:
declare @FinalResults table
while (select COUNT(*) from @PrelimResults) > 0
begin
select top 1 @CurrID = [UID], @Text = Text from @PrelimResults
declare @TextLength int = LEN(@Text )
declare @IndexOfDot int = CHARINDEX('.', REVERSE(@Text ), @TextLength - dbo.RegExIndexOf(@Text, '\b' + @FirstSearchWord + '\b') + 1)
set @Text = SUBSTRING(@Text, case @IndexOfDot when 0 then 0 else @TextLength - @IndexOfDot + 3 end, 300)
while (select COUNT(*) from @TempSearchWords) > 0
begin
select top 1 @CurrWord = Word from @TempSearchWords
set @Text = dbo.RegExReplace(@Text, '\b' + @CurrWord + '\b', '<b>' + SUBSTRING(@Text, dbo.RegExIndexOf(@Text, '\b' + @CurrWord + '\b'), LEN(@CurrWord) + 1) + '</b>')
delete from @TempSearchWords where Word = @CurrWord
end
insert into @FinalResults
select * from @PrelimResults where [UID] = @CurrID
delete from @PrelimResults where [UID] = @CurrID
end
Várias notas:
1. Os loops while aninhados provavelmente não são a maneira mais eficiente de fazer isso, no entanto, nada mais vem à mente. Se eu fosse usar cursores, seria essencialmente a mesma coisa?
2.
@FirstSearchWord
aqui para refere-se à primeira instância no texto de uma das palavras de pesquisa originais, portanto, essencialmente, o texto que você está substituindo estará apenas no resumo. Novamente, é um método bastante básico, algum tipo de algoritmo de localização de cluster de texto provavelmente seria útil.3. Para obter RegEx em primeiro lugar, você precisa de funções CLR definidas pelo usuário.