Как создать все ребра, используя одно выражение в 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))