Я пытаюсь создать систему рекомендаций для бедных для интернет-магазина.
Я хочу реализовать такую функцию Amazon «Клиенты, которые купили этот товар, также купили», и я много об этом читал.
Я знаю, что это Apache Mahout, но я не могу настроить сервер таким образом. Тогда был бы API прогнозирования Google, но он стоил денег, поэтому я сам начал экспериментировать.
Я получил историю заказов с 250 000+ элементами и написал вложенный MySQL Query для поиска заказов, содержащих текущую статью, ранжирования других элементов заказа и сортировки этой таблицы для ранжирования, поэтому я получил набор продуктов, которые заказали другие люди вместе с текущей статьей.
Проблема в том, что запрос может занять до 10 секунд, поэтому его нельзя использовать напрямую.
Я подумал о таблице кэширования, но этот запрос останавливается через 20 минут (есть 60 000 товаров и 250 000 заказанных товаров), поэтому я не могу заполнить эту таблицу.
Мой текущий обходной путь следующий:
HTML рекомендации загружается через AJAX ondocumentready, поэтому сайт загружается, а рекомендация загружается в фоновом режиме. Данные рекомендаций обрабатываются один раз и сохраняются в файловом кэше (простой кэш PEAR), поэтому в следующий раз они загружаются быстрее. Таким образом, кеш создается по запросу, если кто-то посещает сайт, и хранится в течение дня или, возможно, недели.
Я спрашиваю себя и вас, будет ли это приемлемым подходом или это глупо и бесполезно?
Было бы лучше хранить кэшированные данные в БД или в файле (я думаю о производительности и параллельных попаданий). Я имею в виду, что в худшем случае я получу 60 000 кеш-файлов.
Я бы предпочел предварительно вычисленную таблицу со всеми данными, но, как я уже сказал, это занимает много времени, и я не знаю, как ее оптимизировать. (Ожидание, пока чувак SQL вернется из отпуска ^^)
Спасибо за любую подсказку, мнение.
кстати. это запрос:
SELECT c.ArtNr as artnr , count(c.ArtNr) as rank, s.ArtNr as parent_artnr
FROM (
SELECT a.ID_order, a.ArtNr
FROM net_orderposition a
WHERE a.ArtNr = 'TT-PV0005'
) s
JOIN net_orderposition c
WHERE s.ID_order = c.ID_order AND s.ArtNr != c.ArtNr
GROUP BY c.ArtNr
ORDER BY rank DESC,c.Stamp DESC
LIMIT 10;
EDIT:
Я думал о данных ответах и думаю, что они похожи на мою первоначальную идею.
Код выше приведен в следующей таблице:
ID,ParentID , ChildID , Rank
1, TT-PV0005, TT-PV0040, 220
2, TT-PV0005, TT-PV0355, 135
3, TT-PV0005, TT-PV0450, 134
4, TT-PV0005, TT-PV0451, 89
5, TT-PV0005, RH-01V2 , 83
6, TT-PV0005, TT-PV0041, 83
7, TT-PV0005, TT-PV0353, 82
8, TT-PV0005, TT-PV0037, 80
ParentID - это текущий элемент, ChildID - элементы, которые заказывались в прошлом вместе с ParentID, Rank - это предварительно вычисленный счетчик того, как часто ребенок заказывается с текущим элементом.
Теперь я могу обновлять или вставлять связанные элементы в каждом новом заказе и подсчитывать ранг, если он уже присутствует в БД.
Единственное, чего я боюсь, я окажусь за действительно очень большим столом.
Может быть, это не должно быть проблемой, если я пересчитываю его в автономном режиме раз в неделю?
Но тогда мне нужно оптимизировать запрос, чтобы он не занимал 10 секунд на элемент.
Что ты думаешь?