Консультация по Neo4J

1 000 руб.за час • безналичный расчёт, электронные деньги
03 октября 2017, 13:51 • 0 откликов • 21 просмотр
Интернет-магазин продаёт авто-товары. Нужно искать пары рекомендуемых товаров в тех же категориях с учётом дополнительных статистических ограничений. Сейчас в голове крутятся варианты на MySQL и Neo4J. Судя по графикам производительности, мне нужен будет именно Neo4J, но я не понимаю, как реализовать поиск с учётом агрегатных функций.

Модель данных
У каждой покупки есть дата
В одной покупке не менее одного товара.
У каждого товара есть стоимость.
У каждого товара есть не менее одной категории.

С точки SQL была бы такая модель
<code lang="sql">
CREATE TABLE `product` (
`productId` INT(11) NOT NULL,
PRIMARY KEY (`productId`),
);

CREATE TABLE `product_category` (
`productId` INT(11) NOT NULL,
`categoryId` INT(11) NOT NULL,
PRIMARY KEY (`productId`,`categoryId`)
);

CREATE TABLE `purchase` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`productId` INT(11) NOT NULL,
`purchasedAt` datetime NOT NULL,
`productPairId` INT(11) NOT NULL,
`price` decimal(13,2) NOT NULL,
PRIMARY KEY (`id`)
);
</code>

В частности, мне нужно выполнить поиск по такому запросу:
Для заданного товара найти 5 товаров в тех же категориях, но чтобы цена была не меньше чем у этого товара и первыми были те, которые покупают чаще за последние 30 дней.

Пример:
Были покупки:
1. "Фара модель 1" (категория "электрооборудование") за 1000р была куплена вместе с "Сигнал" (электрооборудование) за 500р
2. "Фара модель 2" (категория "электрооборудование") за 500р была куплена вместе с "Охлаждающая жидкость" (Технические жидкости) за 800р
3. "Фара модель 2" (категория "электрооборудование") за 500р была куплена вместе с "Набор ковриков" (Салон) за 1500р

Теперь если я сделаю запрос "пара для товара "Сигнал за 500 рублей", мне должен вернуть "Фара модель 1", потому что это тоже "электрооборудование", но цена выше чем у "Сигнал" и покупка была в последние 30 дней.

На SQL запрос был бы такой (приблизительно):
<code lang="sql">
SELECT pc2.productId, -- найти парный товар
(SELECT COUNT(id) -- определить количество продаж
FROM purchase pr
WHERE ((pr.productId = pc.productId AND pr.productPairId = pc2.productId)
OR -- чтобы продажи были в паре
(pr.productId = pc2.productId AND pr.productId = pc.productId)
)
AND pr.price > '500 рублей' -- и цена больше чем у товара
AND purchasedAt > '30 дней назад' -- и не очень давно
) as cnt
FROM productCategory pc
JOIN productCategory pc2 ON pc2.categoryId = pc.categoryId -- и чтобы товары были в одной категории
WHERE pc.productId = 'Сигнал'
ORDER BY cnt DESC -- по убыванию количества продаж
LIMIT 5 -- только 5 результатов из найденных
</code>

Как такое же сделать на Neo4J?