8

Mamy aplikację internetową, która używa SQL Server 2008 jako bazy danych. Nasi użytkownicy mogą wykonywać wyszukiwania pełnotekstowe na poszczególnych kolumnach w bazie danych. Wydaje się, że funkcja pełnego tekstu SQL Server nie zapewnia obsługi podświetlania trafień. Czy musimy to zbudować sami, czy może istnieje jakaś biblioteka lub wiedza na temat tego, jak to zrobić?Jak zrobić wyróżnianie hitem wyników zapytania SQL pełnotekstowego serwera

BTW wniosek jest napisany w języku C#, więc rozwiązanie .Net byłoby idealne, ale nie jest konieczne, ponieważ moglibyśmy przetłumaczyć.

+0

http://www.sqlperformance.com/2012/09/t-sql-queries/hit-highlighting-in-full-text-search –

Odpowiedz

3

Rozbudowując pomysł Ishmaela, nie jest to ostateczne rozwiązanie, ale uważam, że to dobry sposób na rozpoczęcie.

Po pierwsze musimy uzyskać listę słów, które zostały pobrane z silnikiem pełnotekstowe:

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' 

Istnieje już sporo można rozszerzyć na przykład na wzór wyszukiwania jest dość proste, ; Są też prawdopodobnie lepsze sposoby na odfiltrowanie słów, których nie potrzebujesz, ale przynajmniej daje ci listę słów łodygi itp., które zostałyby dopasowane przez wyszukiwanie pełnotekstowe.

Po uzyskaniu pożądanych wyników, można użyć polecenia RegEx, aby przeanalizować zestaw wyników (lub najlepiej tylko podzestaw, aby przyspieszyć, chociaż jeszcze nie znalazłem dobrej metody). W tym celu po prostu korzystać z dwóch pętli while i kilka tabeli tymczasowej i zmienne:

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 Uwagi:
1. Pętle zagnieżdżone natomiast prawdopodobnie nie są najbardziej skuteczny sposób to zrobić, ale nic jeszcze przychodzi mi na myśl. Gdybym używał kursorów, to w zasadzie byłaby to ta sama rzecz?
2. @FirstSearchWord tutaj, aby odnieść się do pierwszej instancji w tekście jednego z oryginalnych słów wyszukiwania, więc zasadniczo tekst, który zastępujesz, znajduje się tylko w podsumowaniu. Ponownie, jest to dość podstawowa metoda, pewien algorytm wyszukiwania grupowego prawdopodobnie byłby przydatny.
3. Aby uzyskać RegEx w pierwszej kolejności, potrzebne są funkcje zdefiniowane przez użytkownika CLR.

1

Być może w tym przypadku brakuje punktu bazy danych. Jego zadaniem jest zwrócenie danych, które spełniają warunki, które mu dałeś. Myślę, że będziesz chciał zaimplementować podświetlanie prawdopodobnie za pomocą regex w twoim kontrolerze sieciowym.

Oto, co ujawni szybkie wyszukiwanie.

http://www.dotnetjunkies.com/PrintContent.aspx?type=article&id=195E323C-78F3-4884-A5AA-3A1081AC3B35

+3

Dzięki za odpowiedź. Chociaż zdaję sobie sprawę, że wykroczenie jest poza zakresem bazy danych, być może baza danych powinna dostarczyć lokalizacje trafień itp., Zamiast polegać na regex itp., Które mogą być trudne/niedokładne, gdy weźmiesz pod uwagę efekty wynikające z zatrzymywania słów, itp. . –

1

Niektóre szczegóły:

  search_kiemeles=replace(lcase(search),"""","") 
      do while not rs.eof 'The search result loop 
       hirdetes=rs("hirdetes") 
       data=RegExpValueA("([A-Za-zöüóőúéáűíÖÜÓŐÚÉÁŰÍ0-9]+)",search_kiemeles) 'Give back all the search words in an array, I need non-english characters also 
       For i=0 to Ubound(data,1) 
        hirdetes = RegExpReplace(hirdetes,"("&NoAccentRE(data(i))&")","<em>$1</em>") 
       Next 
       response.write hirdetes 
       rs.movenext 
      Loop 
      ... 

Funkcje

'All Match to Array 
Function RegExpValueA(patrn, strng) 
    Dim regEx 
    Set regEx = New RegExp ' Create a regular expression. 
    regEx.IgnoreCase = True ' Set case insensitivity. 
    regEx.Global = True 
    Dim Match, Matches, RetStr 
    Dim data() 
    Dim count 
    count = 0 
    Redim data(-1) 'VBSCript Ubound array bug workaround 
    if isnull(strng) or strng="" then 
     RegExpValueA = data 
     exit function 
    end if 
    regEx.Pattern = patrn ' Set pattern. 
    Set Matches = regEx.Execute(strng) ' Execute search. 
    For Each Match in Matches ' Iterate Matches collection. 
     count = count + 1 
     Redim Preserve data(count-1) 
     data(count-1) = Match.Value 
    Next 
    set regEx = nothing 
    RegExpValueA = data 
End Function 

'Replace non-english chars 
Function NoAccentRE(accent_string) 
    NoAccentRE=accent_string 
    NoAccentRE=Replace(NoAccentRE,"a","§") 
    NoAccentRE=Replace(NoAccentRE,"á","§") 
    NoAccentRE=Replace(NoAccentRE,"§","[aá]") 
    NoAccentRE=Replace(NoAccentRE,"e","§") 
    NoAccentRE=Replace(NoAccentRE,"é","§") 
    NoAccentRE=Replace(NoAccentRE,"§","[eé]") 
    NoAccentRE=Replace(NoAccentRE,"i","§") 
    NoAccentRE=Replace(NoAccentRE,"í","§") 
    NoAccentRE=Replace(NoAccentRE,"§","[ií]") 
    NoAccentRE=Replace(NoAccentRE,"o","§") 
    NoAccentRE=Replace(NoAccentRE,"ó","§") 
    NoAccentRE=Replace(NoAccentRE,"ö","§") 
    NoAccentRE=Replace(NoAccentRE,"ő","§") 
    NoAccentRE=Replace(NoAccentRE,"§","[oóöő]") 
    NoAccentRE=Replace(NoAccentRE,"u","§") 
    NoAccentRE=Replace(NoAccentRE,"ú","§") 
    NoAccentRE=Replace(NoAccentRE,"ü","§") 
    NoAccentRE=Replace(NoAccentRE,"ű","§") 
    NoAccentRE=Replace(NoAccentRE,"§","[uúüű]") 
end function 
3

Wygląda jak można analizować dane wyjściowe nowego SQL Server 2008 stored procedure sys.dm_fts_parser i użyć wyrażenia regularnego, ale nie spojrzał na zbyt blisko.

+0

Wydaje się, że wiesz o tym, czy istnieje procedura przechowywana w celu wyodrębnienia tekstu z zawartości nieprzetworzonego pliku (zastosuj typ pliku "filtr")? – Guillaume86

Powiązane problemy