Как я могу идентифицировать несколько тегов слов в текстовом поле в SQL - PullRequest
1 голос
/ 23 февраля 2012

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

Пока у меня есть следующее, что действительно хорошо работает для отдельных слов;

INSERT INTO #tags SELECT Word 
FROM dbo.SplitWords('some colours are blue, green, red and light blue')

SELECT Word
FROM    #tags
INTERSECT
SELECT  Tag
FROM    dbo.Tags

DROP TABLE #tags

Если в моих таблицах тегов есть записи для «зеленого», «красного» и «синего», они возвращаются, как вы могли ожидать.

Я хотел бы знать, как лучше всего добиться аналогичного результата, но для тегов, состоящих из нескольких слов ... например, «голубой»

Я понимаю, что проблема, с которой я столкнулся в приведенном выше коде, заключается в том, что я разделяю исходный текст на отдельные слова, чтобы «голубой» никогда не совпадал, но есть ли другой путь, по которому я мог бы пойти, который не задействует курсоры и т. Д.?

Спасибо за вашу помощь


Просто понял, что следующее достигнет того, что мне нужно

DECLARE @Text as nvarchar(max)

SELECT @Text = 'some colours are blue, green, red and light blue'

SELECT  TagID, 
    Tag 
FROM    Tags 
WHERE   @Text LIKE '% ' + Tag + ' %' 
ORDER BY Tag

Но я боюсь, что это может быть неэффективно, если в моей таблице несколько тысяч строк, а искомая текстовая строка очень длинная.

У кого-нибудь есть мысли о том, как я мог бы сделать тот же процесс более эффективно?

Ответы [ 2 ]

0 голосов
/ 27 ноября 2012

ОК, я согласился на свое предыдущее решение, пока у меня не было времени переосмыслить / подождать, пока оно не станет проблемой. Старый метод теперь выполняется слишком долго, заставляя меня найти альтернативное решение.

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

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

Когда я это сделаю, я просто присоединяю свою временную таблицу к своим таблицам БД, чтобы вернуть все детали фраз, которые мне нужны.

Пример кода ниже:

DECLARE @PageText nvarchar (max) - параметр текста страницы

CREATE TABLE # Совпадения (PhraseID int)

ОБЪЯВИТЬ @PhraseID int ОБЪЯВИТЬ @PhraseText nvarchar (100)

ОБЪЯВИТЬ curMatchingPhrases CURSOR FAST_FORWARD FORWARD_ONLY FOR ВЫБЕРИТЕ p.PhraseID, p.PhraseText ОТ фразы p

OPEN curMatchingPhrases

FETCH NEXT FROM curMatchingPhrases INTO @PhraseID, @PhraseText

WHILE @@ FETCH_STATUS = 0 НАЧАТЬ

IF EXISTS (SELECT 'match' WHERE @PageText LIKE '% ' + @PhraseText + ' %')
BEGIN
    INSERT #Matches SELECT  @PhraseID
    WHERE   @PhraseID NOT IN (SELECT PhraseID FROM #Matches)
END

FETCH NEXT FROM curMatchingPhrases INTO @PhraseID, @PhraseText 

END

ЗАКРЫТЬ curMatchingPhrases DEALLOCATE curMatchingPhrases

SELECT * FROM # Matches

DROP TABLE # Matches

Я уверен, что другие здесь смогут найти более элегантные решения, но курсор уменьшил SP на 6 + сек до 0 - 1 сек для меня, так что я счастлив сейчас.

Mojo

0 голосов
/ 09 мая 2012

Ознакомьтесь с моим ответом по TSQL - Объединение с использованием полнотекстового CONTAINS

Оно использует идею @ Conrad, но позволяет преодолеть ограничение переменной CONTAINS

...