Как создать все ребра, используя одно выражение в Cypher?

Как создать все ребра, используя одно выражение в Cypher?

Например: допустим, у меня есть один объект, подобный этому

Employees {name: "abc, country: "NZ", zipcode: "123456"}

Employees {name: "def", country: "AUS", zipcode: "964573"}

и скажем, у меня есть следующие объекты диспетчера

Manager { name: "abc", depatment: "product"}

Manager {name: "abc", depatment: "sales"}

Manager {name: "abc", depatment: "marketing"}

и, наконец, объекты адреса

Address {zipcode: "964573", street: "Auckland St"}

Теперь я хочу создать все края, где Employees.name = Manager.name and Employees.zipcode = Address.zipcode Однако если Employees.name != Manager.name но Employees.zipcode = Address.zipcode тогда я хочу, чтобы все края были созданы между Employees а также Address аналогично если Employees.zipcode != Address.zipcode но Employees.name = Manager.nameтогда я хочу, чтобы все края были созданы между Employees а также Manager, И я хочу добиться всего этого в одном утверждении / запросе

Проще говоря, если есть совпадающие вершины между Сотрудниками, Менеджером и Адресом, я хочу, чтобы между ними были созданы все ребра, но если между этими двумя вершинами есть только совпадение, я хочу, чтобы ребро тоже было создано. И я пытаюсь все это в одном запросе / утверждении?

Можно ли написать запрос в одном операторе, который может удовлетворить все вышеперечисленные условия?

То, что я пробовал до сих пор, это

Сначала найдите пары с предложением MATCH, а затем СОЗДАЙТЕ связь между ними.

MATCH (e:Employees),(m:Manager), (a:Address)
WHERE e.name=m.name or e.zipcode = a.zipcode
WITH e,m,a
CREATE (m)-[:REL_NAME]->(e), (e)-[:ADDR_REL]->(a)

Это явно не будет работать из-за Where оговорка, потому что если e.name=m.name затем e.zipcode = a.zipcode не будет проверяться, и, следовательно, не будет создано никаких границ между сотрудниками и адресом.

1 ответ

Решение

Следующий запрос позволяет избежать создания декартового произведения всех трех узловых меток (и будет работать лучше, если у вас есть индексы для :Manager(name) а также :Address(zipcode)):

MATCH (e:Employees)
OPTIONAL MATCH (m:Manager)
WHERE e.name = m.name
WITH e, COLLECT(m) AS mList
FOREACH(x IN mList | CREATE (x)-[:REL_NAME]->(e))
WITH e
OPTIONAL MATCH (a:Address)
WHERE e.zipcode = a.zipcode
WITH e, COLLECT(a) AS aList
FOREACH(y IN aList | CREATE (e)-[:ADDR_REL]->(y))
Другие вопросы по тегам