Question

Nous avons une application Web qui utilise SQL Server 2008 comme base de données. Nos utilisateurs peuvent effectuer des recherches en texte intégral sur des colonnes particulières de la base de données. La fonctionnalité de texte intégral de SQL Server ne semble pas prendre en charge la mise en surbrillance des résultats. Avons-nous besoin de construire cela nous-mêmes ou existe-t-il une bibliothèque ou des connaissances sur la manière de procéder?

BTW l’application étant écrite en C #, une solution .Net serait idéale mais non nécessaire car nous pourrions la traduire.

Était-ce utile?

La solution

En développant l’idée d’Ismaël, ce n’est pas la solution finale, mais je pense que c’est une bonne façon de commencer.

Tout d'abord, nous devons obtenir la liste des mots récupérés avec le moteur de recherche en texte intégral:

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'

On peut déjà développer beaucoup de choses, par exemple, le modèle de recherche est assez basique; de plus, il existe probablement de meilleurs moyens de filtrer les mots dont vous n’avez pas besoin, mais le moins que l’on puisse vous donner est une liste de mots clés, etc. auxquels une recherche en texte intégral pourrait correspondre.

Après avoir obtenu les résultats dont vous avez besoin, vous pouvez utiliser RegEx pour analyser l'ensemble de résultats (ou de préférence un sous-ensemble pour l'accélérer, bien que je n'ai pas encore trouvé le moyen de le faire). Pour cela, j'utilise simplement deux boucles while et un groupe de tables et de variables temporaires:

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

Plusieurs remarques:
1. Les boucles while imbriquées ne sont probablement pas le moyen le plus efficace de le faire, mais rien d'autre ne me vient à l'esprit. Si je devais utiliser des curseurs, ce serait essentiellement la même chose?
2. @FirstSearchWord fait ici référence à la première instance dans le texte de l'un des mots de recherche d'origine. Le texte que vous remplacez ne figurera donc que dans le résumé. Encore une fois, c'est une méthode assez basique, une sorte d'algorithme de recherche de groupe de texte serait probablement pratique.
3. Pour obtenir RegEx en premier lieu, vous avez besoin des fonctions CLR définies par l'utilisateur.

Autres conseils

Il semble que vous puissiez analyser la sortie du nouveau SQL Server 2008 stocké Utilisez la procédure sys.dm_fts_parser et utilisez regex, mais je ne l'ai pas trop regardée.

Il se peut que vous manquiez le point de la base de données dans cette instance. Son travail consiste à vous renvoyer les données qui répondent aux conditions que vous lui avez données. Je pense que vous voudrez implémenter la surbrillance en utilisant probablement regex dans votre contrôle Web.

Voici quelque chose qu'une recherche rapide révélerait.

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

Quelques détails:

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

Fonctions

'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
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top