Rozšíření Ishmaelovy myšlenky, není to konečné řešení, ale myslím, že je to dobrý způsob, jak začít.
Nejprve potřebujeme získat seznam slov, která byla získána pomocí fulltextového nástroje:
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'
Je toho již poměrně hodně, co lze rozšířit, například vyhledávací vzorec je zcela základní; také pravděpodobně existují lepší způsoby, jak odfiltrovat slova, která nepotřebujete, ale alespoň vám to poskytne seznam kmenových slov atd., která by odpovídala fulltextovému vyhledávání.
Poté, co získáte výsledky, které potřebujete, můžete pomocí RegEx analyzovat sadu výsledků (nebo nejlépe pouze podmnožinu, abyste ji urychlili, i když jsem ještě nepřišel na dobrý způsob, jak to udělat). K tomu jednoduše používám dvě cykly while a spoustu dočasných tabulek a proměnných:
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
Několik poznámek:
1. Vnořené while smyčky pravděpodobně nejsou nejúčinnějším způsobem, jak to udělat, ale nic jiného mě nenapadá. Kdybych použil kurzory, bylo by to v podstatě to samé?
2. @FirstSearchWord
zde to odkazuje na první výskyt v textu jednoho z původních hledaných slov, takže text, který nahrazujete, bude v podstatě pouze v souhrnu. Opět je to docela základní metoda, nějaký druh algoritmu hledání textového clusteru by se pravděpodobně hodil.
3. Chcete-li získat RegEx na prvním místě, potřebujete uživatelsky definované funkce CLR.