Справка по поиску SQL - PullRequest
0 голосов
/ 25 октября 2009

У меня проблема с нахождением головы вокруг этого. У меня есть таблица со следующей структурой. Содержит около 5 миллионов строк.

Идентификатор bigint основной идентификатор, автоинкремент
SKU int
Ключевое слово nvarchar (200)
KeywordType nvarchar (1)

Таблица разбита на все возможные ключевые слова на нескольких языках для данного SKU. Таким образом, например, продукт «Властелин колец» может иметь 100 записей из-за разных допустимых ключевых слов, но с одним и тем же SKU. Пока игнорируйте KeywordType.

Проблема № 1: Как мне написать SQL-запрос для возврата записей, основанных на вводе, таком как «Властелины колец»?

Проблема № 2: Поле KeywordType является странным. Его следует использовать для фильтрации записей на основе формата, например, CD, DVD и т. Д. Таким образом, значение KeywordType «X» для данного набора результатов SKU должно быть дополнительно отфильтровано по его значению. Например, пользователь ищет "Lord Rings" с фильтром DVD. Мне нужны результаты, начиная с выпуска № 1, а также только те, которые имеют ключевое слово "DVD" И KeywordType "X".

Наконец, я ищу решение ANDed. Благодарю. Надеюсь, кто-то может помочь ...

Вот некоторые примеры данных для конкретного SKU для Властелина Колец Двух Башен

650446 12288 DVD F 
650452 12288 LORD T 
650453 12288 LTD X 
650454 12288 MOVIE A 
650455 12288 OF T 
650457 12288 RINGS T 
650460 12288 THE T 
650461 12288 TOURS X 
650462 12288 TOWERS T 
650463 12288 TWO T

Если пользователь введет "Lord Rings", то я ожидаю, что вышеуказанный SKU будет возвращен в результатах поиска.

Ответы [ 3 ]

0 голосов
/ 25 октября 2009

Убедитесь, что у вас есть индекс для Keyword и KeywordType!

Вариант 1. Динамическое построение запроса с помощью цикла. Не указан язык, поэтому псевдокод ....

foreach $var ( 'search','terms','here' ) {
  $query .= "Keyword = $var AND";
}
chop last 4 characters.
SELECT SKU,COUNT(Id) AS score FROM blah 
WHERE ( $query ) AND KeywordType = ? 
GROUP BY SKU ORDER BY score DESC

Вариант 2: использовать IN. (Я обычно нахожу это медленнее)

SELECT SKU,COUNT(Id) AS score FROM blah 
WHERE Keyword IN ('search','terms','here' ) AND KeywordType = ? 
GROUP BY SKU ORDER BY score DESC

Под 'И' я полагаю, вы имеете в виду группирование ваших матчей по SKU.

GROUP BY даст вам это. Это даст вам совпадающие записи, с теми, которые первыми соответствуют большинству ключевых слов.

Только точное совпадение ключевых слов. Если вы хотите не точно, вы вернулись к использованию LIKE. LIKE на 5 миллионов строк на самом деле не вариант.

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

Очевидно, что поисковые термины необходимо очистить, но это зависит от языка / базы данных.

0 голосов
/ 25 октября 2009

Вопрос немного сбивает с толку, но я думаю, что вам нужно:

1) Способ анализа пользовательского ввода (например, "Lord Ring") в отдельные ключевые слова (например, ("Lord", "Ring")). Желательно, чтобы это делалось на уровне приложения, но может быть выполнено в SQL / PSQL / TSQL, т. Е. Практически в любой разновидности SQL.

2) SQL-запрос, подобный этому (полученный из решения Дарена Швенке)

SELECT SKU, COUNT(*) AS Ranking
FROM tblKeyWords T1     -- or whatever the name
WHERE Keyword IN ('Lord', 'Ring')  -- here the keywords
AND KeywordType = 'T'   -- Optionally be specific on type
AND SKU IN (            -- filter to only take items that are DVDs
     SELECT SKU
     FROM tblKeywords
     WHERE KeywordType = 'X' AND Keyword = 'DVD'
     )
GROUP BY SKU
ORDER BY COUNT(*) DESC

Примечание : эффективность этой структуры для выполнения того, что по сути является формой полнотекстового поиска, оставляет желать лучшего. Ситуацию можно помочь, введя правильные индексы с первого взгляда, которые могут нам понадобиться как минимум - (Ключевое слово, SKU) - (KeywordType, Keyword, SKU)

Несколько других вещей могут помочь, например, исключение нескольких «шумовых слов», таких как «OF», «THE», «A», «TO» из индекса (и, конечно, из критериев поиска, предоставленных концом -Пользователи)

Но в целом может быть хорошей идеей оценить мудрость работы с этой структурой; это может иметь смысл с конкретным приложением под рукой, OP - единственный, кто знает это ...

0 голосов
/ 25 октября 2009

Если KeywordType имеет ограниченное число, так как вы знаете все возможные типы ключевых слов, он будет лучше в качестве ENUM, чем NVARCHAR. Если вы этого не сделаете, я все же рекомендую сделать его NCHAR (1). Типы VARCHAR занимают дополнительное место для хранения длины, поэтому VARCHAR (1) на самом деле больше, чем CHAR (1).

Что касается поиска, попробуйте что-то вроде:

SELECT id, SKU FROM SKUKeywords
WHERE Keyword IN ( 'lord', 'rings' )

Убедитесь, что все ключевые слова совпадают в базе данных, и сделайте то же самое для любого ввода. Для второго просто добавьте условное AND к предложению WHERE следующим образом:

SELECT id, SKU FROM SKUKeywords
WHERE Keyword IN ( 'lord', 'rings' )
  AND KeywordType = 'DVD'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...