Utvidgar Ishmaels idé, det är inte den slutgiltiga lösningen, men jag tror att det är ett bra sätt att börja.
Först måste vi få listan över ord som har hämtats med fulltextmotorn:
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'
Det finns redan ganska mycket man kan utöka, till exempel är sökmönstret ganska grundläggande; Det finns förmodligen också bättre sätt att filtrera bort de ord du inte behöver, men det ger dig åtminstone en lista över stamord etc. som skulle matchas av fulltextsökning.
När du har fått de resultat du behöver kan du använda RegEx för att analysera resultatuppsättningen (eller helst bara en delmängd för att påskynda det, även om jag ännu inte har kommit på ett bra sätt att göra det). För detta använder jag helt enkelt två while-loopar och ett gäng temporära tabeller och variabler:
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
Flera anteckningar:
1. Kapslade while-slingor är förmodligen inte det mest effektiva sättet att göra det på, men inget annat kommer att tänka på. Om jag skulle använda markörer, skulle det i princip vara samma sak?
2. @FirstSearchWord
här refererar till den första instansen i texten av ett av de ursprungliga sökorden, så i huvudsak kommer texten du ersätter bara att finnas i sammanfattningen. Återigen, det är en ganska grundläggande metod, någon sorts algoritm för att hitta textkluster skulle förmodligen vara praktiskt.
3. För att få RegEx i första hand behöver du CLR användardefinierade funktioner.