2012-04-28 2 views
1

Я читал, что вы можете ранжировать результат поиска, используя keepstable вместе с contains и freetext под сервером SQL 2008. Я недавно использовал freetext в первый раз. Свободный текст перебирает слова отдельно и сравнивается с индексированным столбцом. Я хочу, чтобы сначала искать фразы, а затем отдельные слова.Поиск с ранжированием релевантности с использованием keepstable и freetext

Предположим, что колонка описания проиндексирована. Я использую хранимую процедуру запроса, как это:

SELECT id, description, item from table where (FREETEXT(description,@strsearch)) 

если 3 содержит наборы строк слова с яблоками в них, и я искать «яблочный пирог», строка набора с id2 должен быть первым, то другой два должны следовать:

id1 apple pie 4/01/2012 
id2 apple cake 2/29/2011 
id3 candy apple 5/9/2011 

если 4 наборов строк содержат слово с пищей в них, и я ищу «ресторан быстрого питания», строка набор с id3 должен быть первым, а затем id1 (не точное совпадения, но потому что он имеет «фаст-фуд» в колонке), затем должны следовать следующие два:

id1 McDonalds fast food 
id2 healthy food 
id3 fast food restaurant 
id4 Italian restaurant 

ответ

1

Помогает ли эта статья?

MSDN : Limiting Ranked Result Sets (Full-Text Search)

Это означает, в частности, что с помощью дополнительного параметра позволит ограничить результат те, с наибольшей значимостью (которые вы можете повлиять с помощью WEIGHT), а также порядок этой значимости (RANK).

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

В документе нет примера для FREETEXT; он ссылается только на CONTAINSTABLE. Но это определенно означает, что CONTAINSTABLE выводит столбец RANK, который вы можете использовать для ORDER BY.

Я не знаю, есть ли способ применить собственное определение релевантности. Возможно, имеет смысл вытащить 10 лучших соответствий в соответствии с FTS, а затем применить свой собственный рейтинг на выходе, например. вы можете разделить условия поиска с помощью функции и упорядочить по количеству совпадающих слов. Для простоты и простого воспроизведения в следующем примере я не использую Full-Text в подзапросе, но вы можете заменить его тем, что вы на самом деле делаете. Сначала нужно создать функцию:

IF OBJECT_ID('dbo.SplitStrings') IS NOT NULL 
    DROP FUNCTION dbo.SplitStrings; 
GO 
CREATE FUNCTION dbo.SplitStrings(@List NVARCHAR(MAX)) 
RETURNS TABLE 
AS 
    RETURN (SELECT Item FROM 
     (SELECT Item = x.i.value('(./text())[1]', 'nvarchar(max)') 
     FROM (SELECT [XML] = CONVERT(XML, '<i>' 
     + REPLACE(@List, ' ', '</i><i>') + '</i>').query('.') 
      ) AS a CROSS APPLY [XML].nodes('i') AS x(i)) AS y 
     WHERE Item IS NOT NULL 
    ); 
GO 

Тогда простой скрипт, который показывает, как выполнить согласование:

DECLARE @foo TABLE 
(
    id INT, 
    [description] NVARCHAR(450) 
); 

INSERT @foo VALUES 
(1,N'McDonalds fast food'), 
(2,N'healthy food'), 
(3,N'fast food restaurant'), 
(4,N'Italian restaurant'), 
(5,N'Spike''s Junkyard Dogs'); 

DECLARE @searchstring NVARCHAR(255) = N'fast food restaurant'; 

SELECT x.id, x.[description]--, MatchCount = COUNT(s.Item) 
FROM 
(
    SELECT f.id, f.[description] 
    FROM @foo AS f 

    -- pretend this actually does full-text search: 
    --where (FREETEXT(description,@strsearch)) 

    -- and ignore how I actually matched:  
    INNER JOIN dbo.SplitStrings(@searchstring) AS s 
    ON CHARINDEX(s.Item, f.[description]) > 0 

    GROUP BY f.id, f.[description] 
) AS x 
INNER JOIN dbo.SplitStrings(@searchstring) AS s 
ON CHARINDEX(s.Item, x.[description]) > 0 
GROUP BY x.id, x.[description] 
ORDER BY COUNT(s.Item) DESC, [description]; 

Результаты:

id description 
-- ----------- 
3 fast food restaurant 
1 McDonalds fast food 
2 healthy food 
4 Italian restaurant 
+0

Большое спасибо. На странице MSDN и вашем коде вы указали мне в правильном направлении. Затем я обнаружил, что http://msdn.microsoft.com/en-us/library/aa172823%28v=sql.80%29.aspx Немного смущает, но проработал через него – Patriotec

+0

@Aaron. Какова цель использования 2 select заявления. Я получаю тот же результат, если я прокомментирую внешний оператор выбора и сдвиг предложение order by на внутренний оператор select. – iMatoria

Смежные вопросы