Как сделать порядок ключевых слов более релевантным в моем поиске? - PullRequest
2 голосов
/ 25 мая 2010

В моей базе данных есть поле ключевых слов , в котором хранится список ключевых слов, разделенных запятыми.

Например, кукла Шрека может иметь следующие ключевые слова:

ogre, green, plush, hero, boys' toys

Кукла "Beanie Baby" (это может быть людоед ) может иметь:

beanie baby, kids toys, beanbag toys, soft, infant, ogre

(Это полностью надуманный пример.)

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

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

Вот упрощенный запрос:

SELECT
p.ProductID         AS ContentID
, p.ProductName     AS Title
, p.ProductCode     AS Subtitle
, 100               AS Rank
, p.ProductKeywords AS Keywords
FROM Products AS p
WHERE FREETEXT( p.ProductKeywords, @SearchPredicate )

Я думаю что-то вроде замены RANK на:

, 200 - INDEXOF(@SearchTerm)            AS Rank

Это "должно" ранжировать результаты ключевых слов по их релевантности

Я знаю, что INDEXOF - это не команда SQL ... но это то, что Я хотел бы выполнить.

Правильно ли я подхожу к этому?

Можно ли сделать что-то подобное?

Имеет ли это смысл?

Ответы [ 2 ]

1 голос
/ 26 мая 2010

Исходя из того, что у вас есть, и того, что вам не нужно изменять существующие структуры, это, в общем-то, показывает, насколько неэффективен SQL Server при работе со строками, но он будет работать. Ходить по логике:

DECLARE
  @ProductKeywords varchar(100)
 ,@SearchPredicate varchar(10)

SET @ProductKeywords = 'The,quick,brown,fox,jumps,over'
SET @SearchPredicate= 'fox'

--  Where in the string your search value is
print charindex(@SearchPredicate, @ProductKeywords)

--  The string up through but not including your search string
print left(@ProductKeywords, charindex(@SearchPredicate, @ProductKeywords))

--  Remove the commas (your delimiter) from the above
print replace(left(@ProductKeywords, charindex(@SearchPredicate, @ProductKeywords)), ',', '')

--  This is how many characters are left
print len(replace(left(@ProductKeywords, charindex(@SearchPredicate, @ProductKeywords)), ',', ''))

--  This is how many delimiters you removed,
--  = the number of words (minus one) from the "first" the found word was,
--  = a weighting factor you can use
print charindex(@SearchPredicate, @ProductKeywords) - len(replace(left(@ProductKeywords, charindex(@SearchPredicate, @ProductKeywords)), ',', ''))

Замените @ProductKeyword на p.ProductKeywords, и это должно сработать. (Обратите внимание, что у меня нулевой опыт работы с механизмом полнотекстовых запросов. Это может повлиять или не повлиять на этот код.)

1 голос
/ 26 мая 2010

Могу ли я предложить другой способ?

А как насчет связанной таблицы ProductKeywords:

ID_ProductKeyword(pk)
ProductID(int)
KeywordID(int)
Weight(int)

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

Дополнительным преимуществом является то, что вы можете динамически обновлять веса в зависимости от того, как часто ключевое слово дает нужный продукт для пользователей. Или вы можете легко добавить ассоциации ключевых слов, если обнаружите, что пропустили одну из них (они искали myers , прежде чем вспомнить, что Шрек - людоед?)

Мои два цента.

...