Espandendo l'idea di Ismaele, non è la soluzione finale, ma penso che sia un buon modo per iniziare.
Per prima cosa dobbiamo ottenere l'elenco delle parole che sono state recuperate con il motore full-text:
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'
C'è già molto su cui si può espandere, ad esempio il modello di ricerca è piuttosto semplice; inoltre ci sono probabilmente modi migliori per filtrare le parole che non ti servono, ma almeno ti dà un elenco di parole staminali ecc. che sarebbero abbinate alla ricerca full-text.
Dopo aver ottenuto i risultati di cui hai bisogno, puoi utilizzare RegEx per analizzare il set di risultati (o preferibilmente solo un sottoinsieme per accelerarlo, anche se non ho ancora trovato un buon modo per farlo). Per questo uso semplicemente due cicli while e un mucchio di tabelle e variabili temporanee:
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
Diverse note:
1. I loop nidificati probabilmente non sono il modo più efficiente per farlo, tuttavia non viene in mente nient'altro. Se dovessi usare i cursori, sarebbe essenzialmente la stessa cosa?
2. @FirstSearchWord
qui a si riferisce alla prima istanza nel testo di una delle parole di ricerca originali, quindi essenzialmente il testo che stai sostituendo sarà solo nel riepilogo. Ancora una volta, è un metodo piuttosto semplice, una sorta di algoritmo di ricerca di cluster di testo sarebbe probabilmente utile.
3. Per ottenere RegEx in primo luogo, sono necessarie le funzioni CLR definite dall'utente.