質問

SQL Server 2008 をデータベースとして使用する Web アプリケーションがあります。当社のユーザーは、データベース内の特定の列に対して全文検索を行うことができます。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 を使用して結果セットを解析できます (または、高速化するためにできればサブセットのみを解析します。ただし、そのための良い方法はまだ思いつきません)。このために、私は単純に 2 つの 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 here to は、元の検索語の 1 つのテキスト内の最初のインスタンスを参照するため、基本的に、置換するテキストは概要にのみ含まれます。繰り返しますが、これは非常に基本的な方法であり、ある種のテキスト クラスター検索アルゴリズムがおそらく便利です。
3.そもそも RegEx を取得するには、CLR ユーザー定義関数が必要です。

他のヒント

新しいの出力を解析できるようです SQL Server 2008 ストアド プロシージャ sys.dm_fts_parser 正規表現を使用しますが、あまり詳しく見ていません。

この例では、データベースの要点を見逃している可能性があります。その仕事は、指定した条件を満たすデータを返すことです。おそらく Web コントロールで正規表現を使用して強調表示を実装するとよいでしょう。

簡単に検索すると次のことがわかります。

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