如何突出显示SQL Server全文查询的结果
我们有一个使用SQL Server 2008作为数据库的Web应用程序。我们的用户能够对数据库中的特定列进行全文搜索。 SQL Server的全文功能似乎不提供对突出显示突出显示的支持。我们是否需要自己构建它,或者周围是否有一些图书馆或者有关如何做到这一点的知识?
顺便说一句,该应用程序是用Cso编写的。.Net解决方案将是理想的选择,但不是必需的,因为我们可以翻译。
解决方案
回答
我们可能在此实例中缺少数据库的要点。它的工作是将满足我们条件的数据返回给我们。我认为我们可能希望在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></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
回答
看起来我们可以解析新的SQL Server 2008存储过程sys.dm_fts_parser的输出并使用regex,但我并没有对其进行仔细研究。
回答
扩展Ishmael的想法,这不是最终的解决方案,但我认为这是一个很好的起点。
首先,我们需要获取使用全文本引擎检索到的单词的列表:
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指的是原始搜索词之一的文本中的第一个实例,因此,实际上,我们要替换的文本只会出现在摘要中。同样,这是一个非常基本的方法,某种文本簇查找算法可能会派上用场。
3.首先要获得RegEx,我们需要CLR用户定义的函数。