Um Ishmaels Idee weiter auszubauen, ist es nicht die endgültige Lösung, aber ich denke, es ist ein guter Anfang.
Zuerst müssen wir die Liste der Wörter abrufen, die mit der Volltext-Engine abgerufen wurden:
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'
Es gibt bereits eine ganze Menge, die man erweitern kann, zum Beispiel ist das Suchmuster ziemlich einfach; außerdem gibt es wahrscheinlich bessere Möglichkeiten, die Wörter herauszufiltern, die Sie nicht benötigen, aber zumindest erhalten Sie eine Liste von Stammwörtern usw., die von der Volltextsuche gefunden würden.
Nachdem Sie die benötigten Ergebnisse erhalten haben, können Sie RegEx verwenden, um die Ergebnismenge zu analysieren (oder vorzugsweise nur eine Teilmenge, um sie zu beschleunigen, obwohl ich noch keinen guten Weg dafür gefunden habe). Dafür verwende ich einfach zwei While-Schleifen und eine Menge temporärer Tabellen und Variablen:
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
Einige Anmerkungen:
1. Verschachtelte While-Schleifen sind wahrscheinlich nicht die effizienteste Methode, aber mir fällt nichts anderes ein. Wenn ich Cursor verwenden würde, wäre es im Wesentlichen dasselbe?
2. @FirstSearchWord
Hier auf bezieht sich auf das erste Vorkommen eines der ursprünglichen Suchwörter im Text, sodass der Text, den Sie ersetzen, im Wesentlichen nur in der Zusammenfassung enthalten sein wird. Auch hier handelt es sich um eine recht einfache Methode, eine Art Textcluster-Suchalgorithmus wäre wahrscheinlich praktisch.
3. Um überhaupt RegEx zu erhalten, benötigen Sie benutzerdefinierte CLR-Funktionen.