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





Возможно, в этом случае вам не хватает точки базы данных. Его задача - вернуть вам данные, которые удовлетворяют заданным вами условиям. Я думаю, вы захотите реализовать выделение, вероятно, используя регулярное выражение в вашем веб-элементе управления.
Вот кое-что, что можно обнаружить при быстром поиске.
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 и использовать регулярное выражение, но я не смотрел на это слишком внимательно.
Вы, кажется, осведомлены об этом, существует ли хранимая процедура для извлечения текста из необработанного содержимого файла (примените тип файла «фильтр»)?
Расширяя идею Измаила, это не окончательное решение, но я думаю, что это хороший способ начать.
Во-первых, нам нужно получить список слов, которые были получены с помощью полнотекстового движка:
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.