Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

Jak wykonać wyróżnianie trafień w wynikach zapytania pełnotekstowego programu SQL Server

Rozwijając ideę Ismaela, nie jest to ostateczne rozwiązanie, ale myślę, że to dobry sposób na rozpoczęcie.

Najpierw musimy uzyskać listę słów, które zostały pobrane za pomocą silnika pełnotekstowego:

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'

Jest już sporo rzeczy, które można rozwinąć, na przykład wzorzec wyszukiwania jest dość prosty; są też prawdopodobnie lepsze sposoby na odfiltrowanie słów, których nie potrzebujesz, ale przynajmniej daje to listę słów rdzeniowych itp., które można dopasować za pomocą wyszukiwania pełnotekstowego.

Po uzyskaniu potrzebnych wyników możesz użyć RegEx do przeanalizowania zestawu wyników (lub najlepiej tylko podzbioru, aby go przyspieszyć, chociaż nie wymyśliłem jeszcze dobrego sposobu, aby to zrobić). W tym celu po prostu używam dwóch pętli while i kilku tymczasowych tabel i zmiennych:

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

Kilka uwag:
1. Zagnieżdżone pętle while prawdopodobnie nie są najskuteczniejszym sposobem na zrobienie tego, jednak nic innego nie przychodzi do głowy. Gdybym miał używać kursorów, to w zasadzie byłoby to samo?
2. @FirstSearchWord tutaj to odnosi się do pierwszego wystąpienia w tekście jednego z oryginalnych wyszukiwanych słów, więc zasadniczo tekst, który zastępujesz, będzie znajdować się tylko w streszczeniu. Ponownie, jest to dość podstawowa metoda, prawdopodobnie przydałby się jakiś algorytm wyszukiwania klastrów tekstu.
3. Aby uzyskać RegEx w pierwszej kolejności, potrzebujesz funkcji zdefiniowanych przez użytkownika CLR.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Kompletny proces kopiowania tabeli z jednej bazy danych do drugiej (eksport-import) w SQL Server

  2. Jak połączyć ze sobą dwa stoły o tej samej liczbie rzędów według ich kolejności?

  3. Zmień nazwy niektórych tabel na Nazwa tabeli + DDMMRRRR

  4. Jak znaleźć login, nazwę użytkownika bazy danych lub role użytkownika domeny sqlserver, który nie ma własnego loginu?

  5. Dynamiczny SQL z pętlą po wszystkich kolumnach w tabeli