sql >> Databáze >  >> RDS >> Sqlserver

Jak provést zvýraznění výsledků z fulltextového dotazu SQL Server

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.



  1. Převeďte minuty do formátu HH24:MI

  2. SQL Counter a returner, zdvojnásobí výsledek

  3. Převést hex na řetězec

  4. Jak mohu zabránit Hibernate + c3p0 + MySql ve vytváření velkého počtu spících připojení?