【问题标题】:How to create all edges that using one statement in Cypher?如何在 Cypher 中使用一条语句创建所有边?
【发布时间】:2019-04-01 09:38:59
【问题描述】:

如何在 Cypher 中使用一条语句创建所有边?

例如:假设我有一个这样的对象

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

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

假设我有以下 Manager 对象

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.nameEmployees.zipcode = Address.zipcode 然后我希望在EmployeesAddress 之间创建所有边缘,类似地如果Employees.zipcode != Address.zipcodeEmployees.name = Manager.name然后我希望在EmployeesManager 之间创建所有边缘。我想在一个语句/查询中实现所有这些

简单地说,如果员工、经理和地址之间存在匹配的顶点,我希望在它们之间创建所有边,但如果任何两个之间只有匹配,我希望在这两个顶点之间创建边。我想在一个查询/语句中完成所有这些?

这是否可以在一条语句中编写一个查询来满足上述所有条件?

到目前为止我尝试的是这个

首先使用 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.namee.zipcode = a.zipcode 不会被检查,因此不会在员工和地址之间创建边缘。

【问题讨论】:

  • 你试过MATCH (e:Employees),(m:Manager), (a:Address) WHERE e.name=m.name or e.zipcode = a.zipcode SET (m)-[:REL_NAME]->(e), (e)-[:ADDR_REL]->(a)吗?
  • 没有。你能解释一下这是如何工作的吗?所以我可以限制我的问题。
  • 现在我看到了,你想要一个match .. where name... set ... UNION match ... where zip ... set ... 看起来你不能把match .. set ..union 混在一起。
  • 我的想法更像Optional match,虽然不确定完整的语法。
  • 你能验证你最后的陈述吗?如果 WHERE 子句中的任何条件为真,我认为这个查询应该同时创建边 REL_NAME 和 ADDR_REL。

标签: neo4j cypher redisgraph


【解决方案1】:

以下查询避免产生所有 3 个节点标签的 cartesian product(如果 indexes 用于 :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))

【讨论】:

  • 我真的需要FOREACH吗?我是 Cypher 的新手,但我从这篇文章 stackoverflow.com/questions/55354623/… 的理解是 WITH 子句可以收集所有对。没有?
  • 另外,网上有没有资料可以告诉我如何设计顶点标签,在查询时可以带来更好的性能?
  • 您不一定需要使用FOREACH,但在您的情况下,这可能是最简单的方法。此外,这种方法使用的模式可以为同一个e 节点重复任意次数(如果您想创建更多的关系类型)。 Cypher 手册有一个query tuning 部分。
  • 很好,这个例子是我试图解决的问题的最简单版本,你是对的我正在寻找一种模式来解决我的问题的大局。我的问题的通用版本是这个假设我有 10K 条消息(你可以认为每条消息都是一个顶点)并且每对消息都由不同的 id 连接。所以说message1,message2由id1连接,其中id1是messages和message2中的字段之一,message 3由id2连接,message3,message 4由id3连接等等..我想创建一个图表。
猜你喜欢
  • 1970-01-01
  • 2017-04-26
  • 2018-08-23
  • 2022-01-18
  • 1970-01-01
  • 2022-12-22
  • 2011-12-05
  • 1970-01-01
  • 2017-01-01
相关资源
最近更新 更多