Моделирование базы данных Neo4j для многоуровневого маркетинга

#neo4j #modeling #graph-databases

#neo4j #моделирование #граф-базы данных

Вопрос:

Я пытаюсь смоделировать графическую базу данных для базы данных neo4j. Вот подробности:

Агенты — Продукты — Звания — Комиссионные.

Будут агенты. Будут продукты (скажем, продукты для здоровья).

Агент присоединится к другому агенту или может присоединиться напрямую. У агента может быть только один родитель, но несколько дочерних элементов. Нет ограничений на ширину и глубину объединения агентов под другими агентами.

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

Узел: агент { имя, возраст, …, ранг} A1, A2, A3…

Узел: Продукт { название, описание, …, цена } P1, P2, P3…

Взаимосвязь: покупки {дата, время, количество, общая оплата}

(Агент) -[:покупки] -> (Продукт)

Агент может приобретать несколько продуктов одновременно. Агент может приобретать один и тот же продукт несколько раз.

пример :

A1{ ‘Джон Доу’, ’34’, …, ‘4’ }

P1{ ‘Px1’, ‘desx1’, …, ‘$ 2.3’ }

A1 -[ :покупки { 03-01-2014, 09.30, 02, ‘$4.6’ } ]-> ( Р1 )

A1 -[ :покупки { 07-01-2014, 13.45, 01, ‘$2.3’ } ]-> ( Р1 )

? Вот где я застрял. Итак, здесь мне нужно создавать отношения [:покупки] каждый раз, когда агент покупает продукт, даже если это один и тот же продукт?

Будут ли эффективными множественные отношения с одним и тем же типом и меткой между одними и теми же двумя узлами в этом сценарии? Поскольку агенты, вероятно, будут часто покупать одни и те же продукты, это создаст большее количество множественных связей между одними и теми же узлами.

Соответствует ли эта модель стандартному принципу моделирования? Может кто-нибудь предложить лучшее моделирование или исправление?

Ответ №1:

Как предложил Стефан, я бы ввел Purchase узлы, которые связаны с продуктами, а также хранят стоимость покупки в этом узле. Таким образом, вы можете ограничить запрос покупками, не углубляясь в поиск продуктов.

 (:Agent)-[:made]->(:Purchase {date: XXX, value: XXX})-[:HAS]->(:Product)
  

Допустим, у нас есть связь :WORKS_FOR для связи дочерних агентов с их родителями:

 (a1:Agent)-[:WORKS_FOR]->(a2:Agent)
  

Этот простой запрос выдаст вам сумму покупок, которые каждый агент совершил сам, без учета его детей:

 MATCH (parent:Agent)-[:MADE]->(p:Purchase) RETURN parent.name, sum(p.value)
  

Теперь, если вы дополнительно хотите учесть покупки дочерних агентов, вы можете сделать:

 MATCH (parent:Agent)-[:MADE]->(p:Purchase) WITH parent, sum(p.value) AS own_value OPTIONAL MATCH (parent)<-[:WORKS_FOR*]-(child:Agent)-[:MADE]->(pc:Purchase) RETURN parent.name, own_value   sum(pc.value) as total_value
  

Ответ №2:

Я предполагаю, что вам часто нужно вычислять сумму всех покупок между конкретным агентом A и продуктом P. Если это так, может быть полезно ввести total_purchases связь между A и P, содержащую сумму. Всякий раз, когда вы добавляете новую покупку, обязательно обновляйте существующую total_purchases взаимосвязь.

Еще одна вещь, которую следует учитывать, — это если текущий подход к установлению purchases отношений скрывает некоторые концепции предметной области. Я могу думать об агентах, размещающих несколько заказов. Каждый заказ содержит несколько позиций, на которые вы в настоящее время ссылаетесь, используя purchases взаимосвязь. Таким образом, заказ будет представлять собой узел, содержащий, например, дату, связанную с 1) агентом и 2) продуктами.

В общем, все, что само по себе является концепцией или имеет идентификатор, должно быть смоделировано как узел.

Комментарии:

1. @ Stefan: Да, будет эффективно ввести узел заказа между агентами и продуктами. Это устраняет необходимость вставлять дату и время для каждой покупки продукта для одного и того же заказа, вместо этого дата и время могут быть включены в качестве свойств заказа узла.