Voortbouwend op het idee van Ishmael, het is niet de definitieve oplossing, maar ik denk dat het een goede manier is om te beginnen.
Eerst moeten we de lijst met woorden ophalen die zijn opgehaald met de full-text engine:
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'
Er is al heel wat om uit te breiden, het zoekpatroon is bijvoorbeeld vrij basic; er zijn waarschijnlijk ook betere manieren om de woorden uit te filteren die je niet nodig hebt, maar het geeft je in ieder geval een lijst met stamwoorden enz. die overeenkomen met zoeken in volledige tekst.
Nadat je de resultaten hebt gekregen die je nodig hebt, kun je RegEx gebruiken om de resultatenset te ontleden (of bij voorkeur alleen een subset om het te versnellen, hoewel ik nog geen goede manier heb gevonden om dit te doen). Hiervoor gebruik ik gewoon twee while-lussen en een aantal tijdelijke tabellen en variabelen:
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
Verschillende opmerkingen:
1. Geneste while-lussen zijn waarschijnlijk niet de meest efficiënte manier om dit te doen, maar er komt niets anders in je op. Als ik cursors zou gebruiken, zou dat in wezen hetzelfde zijn?
2. @FirstSearchWord
here to verwijst naar de eerste instantie in de tekst van een van de originele zoekwoorden, dus in wezen zal de tekst die u vervangt alleen in de samenvatting staan. Nogmaals, het is een vrij eenvoudige methode, een soort algoritme voor het vinden van tekstclusters zou waarschijnlijk handig zijn.
3. Om RegEx in de eerste plaats te krijgen, hebt u door de gebruiker gedefinieerde CLR-functies nodig.