문제

SQL Server 2008을 데이터베이스로 사용하는 웹 애플리케이션이 있습니다.우리 사용자는 데이터베이스의 특정 열에 대해 전체 텍스트 검색을 수행할 수 있습니다.SQL Server의 전체 텍스트 기능은 적중 강조 표시를 지원하지 않는 것 같습니다.이것을 직접 구축해야 합니까? 아니면 이를 수행하는 방법에 대한 라이브러리나 지식이 있습니까?

그런데 응용 프로그램이 C#으로 작성되었으므로 .Net 솔루션이 이상적이지만 번역할 수 있으므로 필요하지는 않습니다.

도움이 되었습니까?

해결책

이스마엘의 아이디어를 확장하면 최종 해결책은 아니지만 시작하는 좋은 방법이라고 생각합니다.

먼저 전체 텍스트 엔진으로 검색된 단어 목록을 가져와야 합니다.

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'

이미 확장할 수 있는 내용이 상당히 많습니다. 예를 들어 검색 패턴은 매우 기본적입니다.또한 필요하지 않은 단어를 필터링하는 더 좋은 방법이 있을 수 있지만 최소한 어간 단어 목록 등을 제공합니다.이는 전체 텍스트 검색과 일치합니다.

필요한 결과를 얻은 후 RegEx를 사용하여 결과 집합을 구문 분석할 수 있습니다(아직 좋은 방법을 찾지는 못했지만 속도를 높이기 위해 하위 집합만 사용하는 것이 좋습니다).이를 위해 나는 두 개의 while 루프와 임시 테이블 및 변수를 사용합니다.

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

몇 가지 참고사항:
1.중첩된 while 루프는 아마도 가장 효율적인 방법은 아니지만 다른 것은 생각나지 않습니다.커서를 사용한다면 본질적으로 똑같을까요?
2. @FirstSearchWord 여기서는 원래 검색어 중 하나의 텍스트에 있는 첫 번째 인스턴스를 참조하므로 대체하려는 텍스트는 요약에만 표시됩니다.다시 말하지만, 이는 매우 기본적인 방법이므로 일종의 텍스트 클러스터 찾기 알고리즘이 아마도 유용할 것입니다.
삼.RegEx를 먼저 얻으려면 CLR 사용자 정의 함수가 필요합니다.

다른 팁

새로운 출력을 구문 분석할 수 있는 것 같습니다. SQL Server 2008 저장 프로시저 sys.dm_fts_parser 정규식을 사용했지만 너무 자세히 살펴 보지 않았습니다.

이 경우 데이터베이스의 요점이 누락되었을 수 있습니다.그 임무는 귀하가 제공한 조건을 충족하는 데이터를 귀하에게 반환하는 것입니다.웹 컨트롤에서 정규식을 사용하여 강조 표시를 구현하고 싶을 것 같습니다.

다음은 빠른 검색을 통해 알 수 있는 내용입니다.

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

일부 세부정보:

            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
            ...

기능

'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
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top