sql >> Database >  >> RDS >> Sqlserver

Het markeren van resultaten van een SQL Server-query met volledige tekst

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.



  1. BESTEL DOOR ASC met Nulls onderaan

  2. Hoe de database deze query in een grote database te optimaliseren?

  3. MySQL-query:match door komma's gescheiden waarde met kolom met door komma's gescheiden tekenreeks

  4. recursieve functie categorie database