Насколько сложно внедрить полнотекстовый поиск в SQL Server?

StackOverflow https://stackoverflow.com/questions/202440

Вопрос

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

Поскольку у меня есть сроки (вы знаете, я сплю 3 часа в сутки, в тот момент, когда я выгляжу как кошка, которую съел и вырвало), я ожидал, что эта страница будет очень похожа на другие, и я стараюсь решить, вонять или нет.Я никогда раньше не выполнял полнотекстовый поиск на странице....это гора, на которую нужно подняться, или есть простое решение?

Спасибо.

Это было полезно?

Решение

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

Однако, если он уже готов к работе, полнотекстовый поиск относительно прост.

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

Удачи :)

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

Полнотекстовый поиск в SQL Server действительно прост: немного настройки и небольшая настройка на стороне запроса, и все готово!Я уже делал это для клиентов менее чем за 20 минут, будучи знакомым с процессом.

Здесь Статья MSDN 2008 г., оттуда выходят ссылки на 2005 версии

Раньше я использовал 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) что-то вроде того.;) Фильтрация?Забудь об этом.

«Насколько это сложно» — сложный вопрос.Например, тот, кто уже сделал это 10 раз, вероятно, посчитает, что это совсем несложно.Все, что я могу сказать, это то, что вам, вероятно, будет намного проще, если вы будете использовать что-то вроде НЛучене вместо того, чтобы катить свой собственный.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top