使用标签A,B和Z,A和B与Z有自己的关系。使用查询
MATCH (a:A)
MATCH (b:B { uuid: {id} })
MATCH (a)-[:rel1]->(z:Z)<-[:rel2]-(b)
WITH a, COLLECT(z) AS matched_z
RETURN DISTINCT a, matched_z
返回A的节点和与A和B有关系的所有节点Z
我一直试图返回一个单独的Z节点数组,B与Z有,但没有A(即missing_z)。我正在尝试进行初始查询以返回B&amp; B之间的所有关系。 ž
results = MATCH (b:B { uuid: {id} })
MATCH (b)-[:rel2]->(z:Z)
RETURN DISTINCT COLLECT(z.uuid) AS z
MATCH (a:A)
MATCH (b:B { uuid: {id} })
MATCH (a)-[:rel1]->(z:Z)<-[:rel2]-(b)
WITH a, COLLECT(z) AS matched_z, z
RETURN DISTINCT a, matched_z, filter(skill IN z.array WHERE NOT z.uuid IN {results}) AS missing_z
对于missing_z,结果似乎没有结果,人们会认为应该填充它。不确定过滤器是否是使用WHERE NOT / IN方案的正确方法。上述2个查询可以合并为1吗?
答案 0 :(得分:1)
在我看来,这里的难点在于任何失败的比赛都会丢弃到目前为止你所匹配的所有内容。但是你的出发点似乎是&#34;所有Z与B.uuid&#34;相关,所以首先从那里收集并过滤/复制。
使用WITH +聚合函数复制+过滤列
如果匹配失败,请使用OPTIONAL MATCH不应删除已收集的行。
如果我理解你要做的事情,那么这个密码应该完成这个工作,并根据需要调整它(如果你需要帮助理解它的任何部分/适应它,请告诉我)
// Match base set
MATCH (z:Z)<-[:rel2]-(b:B { uuid: {id} })
// Collect into single list
WITH COLLECT(z) as zs
// Match all A (ignore relation to Zs)
MATCH (a:A)
// For each a, return a, the sub-list of Zs related to a, and the sub-list of Zs not related to a
RETURN a as a, FILTER(n in zs WHERE (a)-[:rel1]->(n)) as matched, FILTER(n in zs WHERE NOT (a)-[:rel1]->(n)) as unmatched
答案 1 :(得分:0)
此查询可能会执行您想要的操作:
MATCH (z:Z)<-[:rel2]-(b:B { uuid: {id} })
WITH COLLECT(z) as all_zs
UNWIND all_zs AS z
MATCH (a)-[:rel1]->(z)
WITH all_zs, COLLECT(DISTINCT z) AS matched_zs
RETURN matched_zs, apoc.coll.subtract(all_zs, matched_zs) AS missing_zs;
它首先在all_zs
变量中存储与Z
具有rel2
关系的所有b
个节点。即使第二个MATCH
子句匹配那些Z
节点的子集,此集合的内容也不会受到影响。
然后,它会在matched_zs
个all_zs
节点中存储与rel1
个节点具有A
关系的不同matched_zs
个节点。
最后,它返回:
all_zs
集合,matched_zs
中不属于missing_zs
的唯一节点,{{1}}。查询使用方便的APOC函数apoc.coll.subtract来生成后一个返回值。