2012-01-28 5 views
0

Я пытаюсь создать мини-поисковую систему для сайта, содержащего продукты. Я уже рассматривал полнотекстовый поиск, предложение LIKE и т. Д., Но я все еще хочу продолжить свой путь, потому что база данных будет смехотворно огромной (сотни миллионов продуктов).complex mysql select statement

Дизайн выглядит примерно так: у меня есть таблица, соединяющая слова с идентификаторами слов. У меня есть другая таблица, содержащая все пары идентификаторов слов для идентификаторов продуктов, для которых продукт соответствует. Когда пользователь выполняет поиск, скажем, «карты памяти 2gb», сценарий анализирует «2gb» «память» и «карта».

Затем я использую:

SELECT pid 
    FROM indx_0 
WHERE wid = 294 OR wid = 20591 OR wid = 330 

Я заканчиваю с парами слов, соответствующих продуктов.

У меня есть алгоритм PHP, который определяет, какие продукты попадают в верхнюю часть в зависимости от нескольких вещей. но когда я загружаю 380k результатов в php-массив, время выполнения становится смехотворно медленным. так ясно, я не могу этого сделать. но если я могу сказать, что 1000 результатов за слово, выполнение выполняется быстро, но оно не включает в себя все возможные результаты.

в таблице «indx_0» каждый «pid» (идентификатор продукта) уникален для «wid» (word id) .. и, очевидно, некоторые продукты будут иметь более одного совпадения. Я хочу получить те «pid», у которых больше всего совпадений против «wid».

Скажем, 2000 продуктов соответствуют «2gb» и 200 000 подходящих «карт» и 50 000 подходящих «памяти», но только 20 продуктов, соответствующих всем 3 из этих слов, и 200 продуктов, соответствующих сочетанию двух слов.

Возможно ли получить эти 20 продуктов, а также 200 продуктов, которые частично соответствуют?

ответ

2

Возможно, вам потребуется группа по идентификатору продукта и получить счет, который соответствует. Тогда есть порядок по наиболее подсчетам ударили по убыванию ... т.е .: один продукт соответствует всем 3 WIDS и другие просто соответствует 1, то 3 отсчет будет первым в списке

SELECT pid, count(*) WordMatchCount 
    FROM indx_0 
    WHERE pid in (294, 20591, 330) 
    group by pid 
    order by WordMatchCount desc 
    limit 1000 
+0

вау спасибо так много! только одна вещь, которую мне нужно было изменить ... «ГДЕ pid in» на самом деле «WHERE wid in». кроме того, что он работает так же, как я этого хотел. – nick