Как создать все ребра, используя одно выражение в Cypher? - PullRequest
0 голосов
/ 01 апреля 2019

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

1 голос
/ 01 апреля 2019

Следующий запрос исключает создание декартового произведения из всех трех меток узлов (и будет работать лучше, если у вас есть индексы для :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))
...