Насколько сложно включить полнотекстовый поиск с SQL Server?
Я создаю приложение С#/ASP.NET с бэкэнд SQL. Я нахожусь в крайнем сроке и заканчиваю свои страницы, из левого поля один из моих дизайнеров включил полнотекстовый поиск на одной из моих страниц. Мои "поисковые запросы" до этого момента были фильтрами, позволяющими сузить набор результатов с помощью определенных факторов и значений столбцов.
Будучи тем, что я нахожусь в крайнем сроке (вы знаете, что 3 часа спать ночью, в тот момент, когда я выгляжу как что-то, что кошка ела и вздымалась), я ожидал, что эта страница будет очень похожа на других, и я Я пытаюсь решить, нужно ли вонять. Я никогда не делал полный текстовый поиск на странице раньше... это гора, чтобы подняться или есть простое решение?
Благодарю вас.
Ответы
Ответ 1
Во-первых, вам нужно включить полнотекстовый поиск индексации на рабочих серверах, поэтому, если это не так, вам не захочется идти с этим.
Однако, если это уже готово к работе, поиск полного текста относительно прост.
T-SQL имеет 4 предиката, используемых для полнотекстового поиска:
- FREETEXT
- FREETEXTTABLE
- СОДЕРЖИТ
- CONTAINSTABLE
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
Удачи:)
Ответ 2
Полнотекстовый поиск в SQL Server очень прост, немного конфигурации и небольшой настройки в запросе, и вам хорошо идти! Я сделал это для клиентов менее чем за 20 минут до этого, ознакомившись с процессом
Вот статья MSDN 2008, ссылки выходят на версии 2005 года там
Ответ 3
Я использовал dtSearch раньше для добавления полного текстового поиска в файлы и базы данных, и их материал довольно дешев и прост в использовании.
За исключением добавления всего этого и настройки SQL, этот script будет выполнять поиск по всем столбцам в базе данных и рассказать вам, какие столбцы содержат значения, которые вы ищете. Я знаю, что это не "правильное" решение, но вы можете купить некоторое время.
/*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'
Ответ 4
Я был там. Он работает как шарм, пока вы не начнете рассматривать масштабируемость и расширенные функции поиска, такие как поиск по нескольким столбцам, с указанием каждого значения веса.
Например, единственный способ поиска по столбцам Заголовок и Сводная - иметь вычисленный столбец с SearchColumn = CONCAT(Title, Summary)
и индекс над SearchColumn
. Взвешивание? SearchColumn = CONCAT(CONCAT(Title,Title), Summary)
что-то в этом роде.;) Фильтрация? Забудьте об этом.
Ответ 5
"Как тяжело это" - это трудный вопрос для ответа. Например, кто-то, кто уже сделал это 10 раз, вероятно, подумает об этом. Все, что я могу сказать, это то, что вы, вероятно, найдете это намного проще, если вы используете что-то вроде NLucene, а не сворачиваете свои собственные.