Я создаю приложение C# / ASP.NET с серверной частью SQL. Я нахожусь в крайнем сроке и заканчиваю свои страницы. Не в левом поле один из моих дизайнеров встроил полнотекстовый поиск на одну из моих страниц. Мои «поиски» до этого момента были фильтрами, позволяющими сузить набор результатов по определенным факторам и значениям столбцов.
Поскольку у меня крайний срок (вы знаете, 3 часа сна в сутки, в тот момент, когда я выгляжу как что-то, что кошка съела и вырвало), я ожидал, что эта страница будет очень похожа на другие, и я пытаюсь решить, вонять или нет. Я никогда раньше не выполнял полнотекстовый поиск на странице .... это гора, на которую нужно подняться, или есть простое решение?
Спасибо.





«Насколько это сложно» - сложный вопрос. Например, тот, кто уже проделал это 10 раз, вероятно, сочтет, что это несложно. Все, что я действительно могу сказать, это то, что вам, вероятно, будет намного проще, если вы будете использовать что-то вроде NLucene, а не кататься самостоятельно.
Полнотекстовый поиск в SQL Server действительно прост, небольшая настройка и небольшая настройка на стороне запроса, и все готово! Я сделал это для клиентов менее чем за 20 минут, так как был знаком с процессом
Вот Статья MSDN 2008 г., ссылки на версии 2005 оттуда выходят
Во-первых, вам нужно включить индексирование с полнотекстовым поиском на производственных серверах, так что, если это не входит в область действия, вы не захотите использовать это.
Однако, если он уже готов, полнотекстовый поиск относительно прост.
В T-SQL есть 4 предиката, используемых для полнотекстового поиска:
FREETEXT - самый простой, и его можно сделать так:
SELECT UserName
FROM Tbl_Users
WHERE FREETEXT (UserName, 'bob' )
Results:
JimBob
Little Bobby Tables
FREETEXTTABLE работает так же, как FreeTEXT, за исключением того, что возвращает результаты в виде таблицы.
Настоящая мощь полнотекстового поиска T-SQL исходит из предиката CONTAINS (и CONTAINSTABLE) ... Этот предикат огромен, поэтому я просто вставлю его использование в:
CONTAINS
( { column | * } , '< contains_search_condition >'
)
< contains_search_condition > ::=
{ < simple_term >
| < prefix_term >
| < generation_term >
| < proximity_term >
| < weighted_term >
}
| { ( < contains_search_condition > )
{ AND | AND NOT | OR } < contains_search_condition > [ ...n ]
}
< simple_term > ::=
word | " phrase "
< prefix term > ::=
{ "word * " | "phrase * " }
< generation_term > ::=
FORMSOF ( INFLECTIONAL , < simple_term > [ ,...n ] )
< proximity_term > ::=
{ < simple_term > | < prefix_term > }
{ { NEAR | ~ } { < simple_term > | < prefix_term > } } [ ...n ]
< weighted_term > ::=
ISABOUT
( { {
< simple_term >
| < prefix_term >
| < generation_term >
| < proximity_term >
}
[ WEIGHT ( weight_value ) ]
} [ ,...n ]
)
Это означает, что вы можете писать такие запросы, как:
SELECT UserName
FROM Tbl_Users
WHERE CONTAINS(UserName, '"little*" NEAR tables')
Results:
Little Bobby Tables
Удачи :)
Раньше я использовал dtSearch для добавления полнотекстового поиска к файлам и базам данных, и их материалы довольно дешевы и просты в использовании.
За исключением добавления всего этого и настройки SQL, этот сценарий будет искать по всем столбцам в базе данных и сообщать вам, какие столбцы содержат значения, которые вы ищете. Я знаю, что это не «правильное» решение, но может выиграть время.
/*This script will find any text value in the database*/
/*Output will be directed to the Messages window. Don't forget to look there!!!*/
SET NOCOUNT ON
DECLARE @valuetosearchfor varchar(128), @objectOwner varchar(64)
SET @valuetosearchfor = '%staff%' --should be formatted as a like search
SET @objectOwner = 'dbo'
DECLARE @potentialcolumns TABLE (id int IDENTITY, sql varchar(4000))
INSERT INTO @potentialcolumns (sql)
SELECT
('if exists (select 1 from [' +
[tabs].[table_schema] + '].[' +
[tabs].[table_name] +
'] (NOLOCK) where [' +
[cols].[column_name] +
'] like ''' + @valuetosearchfor + ''' ) print ''SELECT * FROM [' +
[tabs].[table_schema] + '].[' +
[tabs].[table_name] +
'] (NOLOCK) WHERE [' +
[cols].[column_name] +
'] LIKE ''''' + @valuetosearchfor + '''''' +
'''') as 'sql'
FROM information_schema.columns cols
INNER JOIN information_schema.tables tabs
ON cols.TABLE_CATALOG = tabs.TABLE_CATALOG
AND cols.TABLE_SCHEMA = tabs.TABLE_SCHEMA
AND cols.TABLE_NAME = tabs.TABLE_NAME
WHERE cols.data_type IN ('char', 'varchar', 'nvchar', 'nvarchar','text','ntext')
AND tabs.table_schema = @objectOwner
AND tabs.TABLE_TYPE = 'BASE TABLE'
ORDER BY tabs.table_catalog, tabs.table_name, cols.ordinal_position
DECLARE @count int
SET @count = (SELECT MAX(id) FROM @potentialcolumns)
PRINT 'Found ' + CAST(@count as varchar) + ' potential columns.'
PRINT 'Beginning scan...'
PRINT ''
PRINT 'These columns contain the values being searched for...'
PRINT ''
DECLARE @iterator int, @sql varchar(4000)
SET @iterator = 1
WHILE @iterator <= (SELECT Max(id) FROM @potentialcolumns)
BEGIN
SET @sql = (SELECT [sql] FROM @potentialcolumns where [id] = @iterator)
IF (@sql IS NOT NULL) and (RTRIM(LTRIM(@sql)) <> '')
BEGIN
--SELECT @sql --use when checking sql output
EXEC (@sql)
END
SET @iterator = @iterator + 1
END
PRINT ''
PRINT 'Scan completed'
Я был там. Он работает как шарм, пока вы не начнете рассматривать масштабируемость и расширенные функции поиска, такие как поиск по нескольким столбцам с присвоением каждому отдельному значению веса.
Например, единственный способ поиска по столбцам Заголовок и Резюме - это иметь вычисляемый столбец с SearchColumn = CONCAT(Title, Summary) и индексировать по SearchColumn. Взвешивание? SearchColumn = CONCAT(CONCAT(Title,Title), Summary) что-то в этом роде. ;) Фильтрация? Забудь об этом.
Я проголосовал за это и исключил его как ответ не только потому, что это отличный и подробный ответ, но и потому, что это ссылка на xkcd. ВЫИГРАТЬ.