Одной из интересных проблем в мире онлайн-покупок с точки зрения ритейлера является выяснение , есть ли подходящий товар-заменитель, если заказанный товар в данный момент отсутствует на складе.
Так как эта проблема объединяет три типа данных — историю заказов, уровень запасов и продукты — кажется, что она должна хорошо подходить для Neo4j, поэтому я привел короткий пример.
Я написал следующий шифр, чтобы создать некоторые продукты, человека, несколько заказов и затем доступность этих продуктов в воображаемом магазине.
CREATE (bakedBeans :Category {name: "Baked Beans"} ) CREATE (fruit :Category {name: "Fruit"} ) CREATE (hbb :Product {name: "Heinz Baked Beans", type: "brand"} ) CREATE (bbb :Product {name: "Branstone Baked Beans", type: "brand"} ) CREATE (sbb :Product {name: "Sainsbury's Baked Beans", type: "own"} ) CREATE (apple :Product {name: "Bag of Apples"} ) CREATE UNIQUE (hbb)-[:HAS_CATEGORY]->(bakedBeans) CREATE UNIQUE (bbb)-[:HAS_CATEGORY]->(bakedBeans) CREATE UNIQUE (sbb)-[:HAS_CATEGORY]->(bakedBeans) CREATE (southwark :Store {name: "Southwark"}) CREATE UNIQUE (southwark)-[:HAS_IN_STOCK {availability: 0}]->(hbb) CREATE UNIQUE (southwark)-[:HAS_IN_STOCK {availability: 2}]->(bbb) CREATE UNIQUE (southwark)-[:HAS_IN_STOCK {availability: 10}]->(sbb) CREATE UNIQUE (southwark)-[:HAS_IN_STOCK {availability: 10}]->(apple) CREATE (mark :Person {name: "Mark"}) CREATE (order1 :Order {id: 1, date: 1380884632}) CREATE UNIQUE (order1)-[:CONTAINS {count: 1}]->(hbb) CREATE UNIQUE (order1)-[:CONTAINS {count: 5}]->(apple) CREATE UNIQUE (mark)-[:PLACED_ORDER]->(order1) CREATE (order2 :Order {id: 2, date: 1380885051}) CREATE UNIQUE (order2)-[:CONTAINS {count: 1}]->bbb CREATE UNIQUE (mark)-[:PLACED_ORDER]->(order2)
Затем у нас может быть новый заказ, который мы пытаемся выполнить, и мы хотим проверить, есть ли продукты в наличии.
Сначала мы создадим заказ:
// Create the order CREATE (order3:Order {id: 3, date: 1380895051}) WITH order3 // Assign the order to Mark MATCH (p:Person) WHERE p.name = "Mark" CREATE UNIQUE (p)-[:PLACED_ORDER]->(order3) WITH order3 // Populate the order with some products MATCH (p:Product) WHERE p.name = "Heinz Baked Beans" CREATE UNIQUE (order3)-[:CONTAINS {count: 2}]->(p) WITH order3 MATCH (p:Product) WHERE p.name = "Bag of Apples" CREATE UNIQUE (order3)-[:CONTAINS {count: 2}]->(p)
Теперь давайте проверим наличие каждого товара в заказе в конкретном магазине:
// Find the products in the order MATCH (o:Order)-[c:CONTAINS]->(product) WHERE o.id = 3 WITH product, c.count AS count // Check which items are out of stock in our store MATCH (s:Store)-[inStock:HAS_IN_STOCK]->(product) WHERE s.name = "Southwark" RETURN product, inStock ==> +--------------------------------------------------------------------------------------------+ ==> | product | inStock | ==> +--------------------------------------------------------------------------------------------+ ==> | Node[11444]{name:"Heinz Baked Beans",type:"brand"} | :HAS_IN_STOCK[60053]{availability:0} | ==> | Node[11447]{name:"Bag of Apples"} | :HAS_IN_STOCK[60056]{availability:10} | ==> +--------------------------------------------------------------------------------------------+
Теперь, если мы изменим этот запрос, чтобы вернуть только те товары, у которых на складе меньше товаров, чем мы пытались заказать, мы увидим, что Запеченные бобы Heinz недоступны:
// Find the products in the order MATCH (o:Order)-[c:CONTAINS]->(product) WHERE o.id = 3 WITH product, c.count AS count // Check which items are out of stock in our store MATCH (s:Store)-[inStock:HAS_IN_STOCK]->(product) WHERE s.name = "Southwark" AND count > inStock.availability RETURN product, inStock ==> +-------------------------------------------------------------------------------------------+ ==> | product | inStock | ==> +-------------------------------------------------------------------------------------------+ ==> | Node[15281]{name:"Heinz Baked Beans",type:"brand"} | :HAS_IN_STOCK[86079]{availability:0} | ==> +-------------------------------------------------------------------------------------------+
MATCH (p:Person)-[:PLACED_ORDER]->order-[c:CONTAINS]->product-[:HAS_CATEGORY]->category WHERE p.name = "Mark" AND category.name = "Baked Beans" AND order.id <> 3 RETURN product.name, product.type, order.id ==> +---------------------------------------------------+ ==> | product.name | product.type | order.id | ==> +---------------------------------------------------+ ==> | "Heinz Baked Beans" | "brand" | 1 | ==> | "Branstone Baked Beans" | "brand" | 2 | ==> +---------------------------------------------------+
Определив Марка как ценителя запеченных бобов под маркой, мы могли бы затем выполнить запрос, чтобы проверить, есть ли в этом магазине другие запеченные бобы под маркой:
MATCH (s:Store)-[inStock:HAS_IN_STOCK]->p-[:HAS_CATEGORY]->c WHERE s.name = "Southwark" AND c.name = "Baked Beans" AND inStock.availability > 0 AND p.type = "brand" RETURN p.name, inStock.availability ==> +------------------------------------------------+ ==> | p.name | inStock.availability | ==> +------------------------------------------------+ ==> | "Branstone Baked Beans" | 2 | ==> +------------------------------------------------+
Это, очевидно, чрезвычайно наивный подход, поэтому я отправился в твиттер в надежде найти более сложный подход:
Существуют ли общие алгоритмы сходства продуктов? например, на основе категории / описания и т. д. Или это очень сильно зависит от домена?
Николь Уайт в настоящее время играет с майнингом правил ассоциации, что звучит интересно.
@ Markhneedham Я уверен, что это может быть! На самом деле я работаю над майнингом правил связывания в базе данных # neo4j с данными транзакций покупок.
— Николь Уайт (@_nicolemargaret)
30 октября 2013 г.
Это описано на его странице в Википедии примерно так:
Основываясь на концепции строгих правил, Ракеш Агравал и др. [2] ввел правила ассоциации для выявления закономерностей между продуктами в крупномасштабных данных о транзакциях, зарегистрированных в торговых точках (POS) в супермаркетах.
Хотя это не совсем то, что я хочу сделать, мне нужно больше посмотреть на это, чтобы увидеть, можно ли применить некоторые идеи.
Я также узнал, что терминология для того, что я ищу, — это алгоритм « похожих предметов », и я думаю, что я хотел бы увидеть гибридную систему рекомендаций, которая сочетает в себе сходство контента и предыдущую историю покупок пользователя.
Я искал вокруг, чтобы посмотреть, есть ли какие-нибудь открытые или анонимные розничные наборы данных, с которыми можно поиграться, но все, с чем я столкнулся, это « Репозиторий наборов данных для частых наборов ». К сожалению, когда я пытался открыть файлы, они, кажется, просто содержат случайные числа, поэтому я, должно быть, делал что-то не так.
Если кто-нибудь знает о наборе данных о розничной торговле, с которым я могу поиграть, пожалуйста, укажите мне правильное направление.