Как выделить результаты полнотекстового запроса SQL Server

У нас есть веб-приложение, использующее SQL Server 2008 в качестве базы данных. Наши пользователи могут выполнять полнотекстовый поиск по определенным столбцам в базе данных. Полнотекстовые функции SQL Server, похоже, не поддерживают выделение попаданий. Нужно ли нам создавать это самим или, возможно, есть какая-то библиотека или знания о том, как это сделать?

Кстати, приложение написано на C#, поэтому решение .Net было бы идеальным, но не необходимым, поскольку мы могли бы переводить.

sqlperformance.com/2012/09/t-sql-queries/…
Aaron Bertrand 25.09.2012 17:56
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
8
1
8 458
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Возможно, в этом случае вам не хватает точки базы данных. Его задача - вернуть вам данные, которые удовлетворяют заданным вами условиям. Я думаю, вы захотите реализовать выделение, вероятно, используя регулярное выражение в вашем веб-элементе управления.

Вот кое-что, что можно обнаружить при быстром поиске.

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

Спасибо за ответ. Хотя я понимаю, что выделение выходит за рамки базы данных, возможно, база данных должна предоставлять местоположения попаданий и т. д., Вместо того, чтобы полагаться на регулярное выражение и т. д., Что может быть трудным / неточным, если вы учитываете эффекты стемминга, стоп-слов и т. д.

Phil Haselden 17.09.2008 03:32

Некоторые детали:

            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 и использовать регулярное выражение, но я не смотрел на это слишком внимательно.

Вы, кажется, осведомлены об этом, существует ли хранимая процедура для извлечения текста из необработанного содержимого файла (примените тип файла «фильтр»)?

Guillaume86 06.02.2018 19:38
Ответ принят как подходящий

Расширяя идею Измаила, это не окончательное решение, но я думаю, что это хороший способ начать.

Во-первых, нам нужно получить список слов, которые были получены с помощью полнотекстового движка:

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.

Другие вопросы по теме