SQL-запрос для соответствия ключевых слов? - PullRequest
1 голос
/ 01 сентября 2011

У меня есть таблица со столбцом nvarchar(max) с текстом, извлеченным из документов Word.Как создать запрос на выборку, который я передам другому списку ключевых слов в качестве параметра и верну строки, упорядоченные по количеству совпадений?

Может быть, это возможно при полнотекстовом поиске?

Ответы [ 2 ]

1 голос
/ 01 сентября 2011

Да, возможно с полнотекстовым поиском и, вероятно, лучшим ответом.Для прямого решения T-SQL вы можете использовать функцию разделения и соединение, например, предполагая, что таблица чисел называется dbo.Numbers (вам может потребоваться выбрать другой верхний предел):

SET NOCOUNT ON;
DECLARE @UpperLimit INT;
SET @UpperLimit = 200000;

WITH n AS
(
    SELECT
        rn = ROW_NUMBER() OVER
        (ORDER BY s1.[object_id])
    FROM sys.objects AS s1
    CROSS JOIN sys.objects AS s2
    CROSS JOIN sys.objects AS s3
)
SELECT [Number] = rn - 1
INTO dbo.Numbers
FROM n
WHERE rn <= @UpperLimit + 1;

CREATE UNIQUE CLUSTERED INDEX n ON dbo.Numbers([Number]);

Ифункция разбиения, которая использует эту таблицу чисел:

CREATE FUNCTION dbo.SplitStrings
(
    @List NVARCHAR(MAX)
)
RETURNS TABLE
AS
    RETURN
    (
        SELECT DISTINCT
            [Value] = LTRIM(RTRIM(
                SUBSTRING(@List, [Number],
                CHARINDEX(N',', @List + N',', [Number]) - [Number])))
        FROM
            dbo.Numbers
        WHERE
            Number <= LEN(@List)
            AND SUBSTRING(N',' + @List, [Number], 1) = N','
    );
GO

Тогда вы можете просто сказать:

SELECT key, NvarcharColumn /*, other cols */
FROM dbo.table AS outerT
WHERE EXISTS
(
  SELECT 1 
    FROM dbo.table AS t 
    INNER JOIN dbo.SplitStrings(N'list,of,words') AS s
    ON t.NvarcharColumn LIKE '%' + s.Item + '%'
    WHERE t.key = outerT.key
);

Как процедура:

CREATE PROCEDURE dbo.Search
    @List NVARCHAR(MAX)
AS
BEGIN
    SET NOCOUNT ON;

    SELECT key, NvarcharColumn /*, other cols */
    FROM dbo.table AS outerT
    WHERE EXISTS
    (
      SELECT 1 
        FROM dbo.table AS t 
        INNER JOIN dbo.SplitStrings(@List) AS s
        ON t.NvarcharColumn LIKE '%' + s.Item + '%'
        WHERE t.key = outerT.key
    );
END
GO

Тогда вы можетепросто передайте @List (например, EXEC dbo.Search @List = N'foo,bar,splunge') из C #.

Это не будет супер быстро, но я уверен, что это будет быстрее, чем вытащить все данные в C # и двойное вложениезациклите его вручную.

0 голосов
/ 01 сентября 2011

how to ... return the rows ordered by the number of [full-text] matches

Я не использовал его сам, но считаю, что SQL Server 2008 поддерживает взвешивание соответствия CONTAINSTABLE, которые могут вам помочь:

            http://msdn.microsoft.com/en-us/library/ms189760.aspx

Если у вас нет движка, который возвращает результаты, взвешенные по количеству совпадений ...

Вы можете написать UDF, который принимает два ввода и возвращает целое число: большое текстовое значение - это первый вход, аслова, которые вы ищете в виде строки с разделителями-запятыми, являются вторыми.Функция возвращает целое число, представляющее либо число различных искомых слов, которые фактически были найдены хотя бы один раз в тексте, либо общее количество раз, когда искомые слова были найдены.Реализация - как весить - зависит от вас.Например, может быть, вы захотите расположить искомые слова в порядке наиболее важного или наименее важного и придать ударению важного слова больший вес, чем поиску менее важного слова.

Затем вы можете использовать свой механизм полнотекстового поиска, чтобы найти все записи, содержащие хотя бы одно из слов (вы ИЛИ их), и вы можете запустить этот набор результатов через скалярную функцию UDF:

             pseudo code

            select title,  weightfunction(summary, 'word1,word2,word3....wordN')
            from docs
            where summary contains ( word1 or word2 or word3 ... or wordN)
            order by weightfunction(summary, 'word1,word2,word3....wordN') desc
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...