Лучший подход для связи узлов графа в Neo4J (Cypher) - PullRequest
0 голосов
/ 04 апреля 2020

Я пытаюсь получить следующую структуру данных в моей графической базе данных Neo4J:

(User)-[:isEmployedBy]->(Company) В то время как каждая «занятость» может иметь несколько «транзакций»

Я рассматриваю следующие варианты и хотел бы услышать, что будет самым «будущим доказательством»:

Simplest:

create
  (matt:Person { name: 'Matt' } ),
  (stackoverflow:Company { name: 'Stackoverflow' }),
  (matt)-[:employed_by { from: date("2000-01-01"), until: date("2010-01-01") }]->(stackoverflow),
  return *

Однако я не могу добавить дополнительные отношения к своей работе (например, транзакции). Я предполагаю, что мой второй подход - мой единственный выбор? Это правильно? (см. ниже)

create
  (matt:Person { name: 'Matt' } ),
  (stackoverflow:Company { name: 'Stackoverflow' }),
  (employment:Employment, { from: date("2000-01-01"), until: date("2010-01-01")}),
  (t1:Payment, { amount: 100 }),
  (t2:Payment, { amount: 50 }),
  (employment)-[:received]->(t1)
  (employment)-[:received]->(t2)
  return *

Я понимаю, что мог бы связать эти транзакции непосредственно с человеком, но мне нужны они, непосредственно связанные с трудоустройством, например: Если человек теряет работу (соединение), все транзакции нужны исчезнуть.

3) Я также мог бы сделать оба соединения:

create
  (matt:Person { name: 'Matt' } ),
  (stackoverflow:Company { name: 'Stackoverflow' }),
  (employment:Employment, { from: date("2000-01-01"), until: date("2010-01-01")}),
  (matt)-[:employed_by { from: date("2000-01-01"), until: date("2010-01-01") }]->(stackoverflow),
  (matt)-[:has_employment]->(employment)<-[:has_employment]-(stackoverflow)
  return *

Хотя я мог бы столкнуться с противоречивыми данными (даты здесь), этот подход дал бы мне выигрыш в производительности запроса, если, скажем, Я только хотел посмотреть, кто кем был нанят, без дополнительной информации / транзакций? (используя: busy_by).

Общий вопрос: хочу ли (или должен) настраивать двунаправленные соединения?

create
  (matt:Person { name: 'Matt' } ),
  (stackoverflow:Company { name: 'Stackoverflow' }),
  (matt)-[:employed_by { from: date("2000-01-01"), until: date("2010-01-01") }]->(stackoverflow),
  (matt)<-[:employs { from: date("2000-01-01"), until: date("2010-01-01") }]-(stackoverflow),
  return *

Опять я получу дублирующую информацию - есть ли польза от этого вообще?

Спасибо за любые подсказки!

1 Ответ

1 голос
/ 04 апреля 2020

Вариант № 3 близок к тому, что я бы порекомендовал, за исключением того, что:

  1. Отношение :employed_by является избыточным и должно быть опущено, чтобы избежать бесполезного расходования памяти, чрезмерного усложнения некоторых запросов и переноса риск несоответствий. Узел Employment содержит одинаковую информацию.
  2. Я бы не стал использовать один и тот же тип отношений по обе стороны от узла Employment, чтобы избежать путаницы и потенциально повысить эффективность будущих запросов.

Кроме того, в стандартном соглашении об именах, используемом neo4j, имена отношений пишутся в верхнем регистре (например, «HAS_EMPLOYMENT»). Это на самом деле помогает упростить чтение кода Cypher.

...