使用带有MATCH的CASE

时间:2017-06-02 16:02:41

标签: neo4j cypher match case

我有一个简单的查询,寻找一个公共节点' x'与许多起始节点a,b,c有关。如果a,b,c没有公共节点x,那么我想比较a,b和b,c对于公共节点' y'和' z'分别。这就是我想象它应该看起来......但当然不起作用。

MATCH p1=(a)-[]->(x) WHERE a.n=1
WITH p1,a,x
MATCH p2=(b)-[]->(x) WHERE b.n=2
WITH p1,p2,a,b,x
MATCH p3=(c)-[]->(x) WHERE c.n=3
WITH p1,p2,p3,a,b,c,x
MATCH CASE WHEN x IS NULL THEN p4=(a)-[]->(y)<-[]-(b) WHERE a.n=1 AND b.n=2 END 
WITH p1,p2,p3,p4,a,b,c,x,y
MATCH CASE WHEN x IS NULL THEN p5=(b)-[]->(z)<-[]-(c) WHERE b.n=2 AND c.n=3 END
RETURN p1,p2,p3,p4,p5,x,y,z

我正在考虑使用CASE来减少冗余并加快查询速度,因为不需要成对搜索a,b b,c如果是常见的&#39; c&#39;找到了。你如何使用CASE创建一个MATCH。也许有比使用CASE更好的方法?

问题背景

我有一个非常大的数据集,相当浅,平均有15个节点深度。我正在寻找网络中公共相关节点形式的多个输入之间的相关性。输入可以包含2到20个连续值,它们的顺序是相关的,因为它们倾向于在相关性中组合在一起。通常所有输入都有一个共同的相关节点,但如果不是,我需要找到其他具有公共节点的顺序分组,即输入1,2 | 2,3 | 3,4,5等等。这是一个问题,即是否开始广泛,减少工作或开始使用一对一次比较下一个输入一个与最后一个的结果。我希望在没有找到结果的情况下,使用CASE来决定如何通过输入进行分组。

就构建网络而言,每个节点的关系数量最少,因此添加元节点可能不会有所帮助。组合输入组以具有单个起始节点将仅以指数方式增加起始节点的数量,此时每个可能的输入有一个 - 大约1000万左右。将它们组合起来会以指数方式增加,所以我认为最好避免,因为我的理解是发现起始节点是查询中最昂贵的部分。对不起,我决定不谈商业案例。

2 个答案:

答案 0 :(得分:2)

此查询应返回x,y和z值的集合。如果xs集合不为空,则您可以选择忽略yszs集合。

MATCH (a {n: 1}), (b {n: 2})-->(w), (c {n: 3})
OPTIONAL MATCH pa=(a)-->(w)
WITH a, b, c, COLLECT(DISTINCT NODES(pa)[1]) AS ys
OPTIONAL MATCH pc=(c)-->(w)
WITH a, b, c, ys, COLLECT(DISTINCT NODES(pc)[1]) AS zs
RETURN a, b, c, apoc.coll.intersection(ys, zs) AS xs, ys, zs;

有关您的用例的有趣注意事项是,b节点需要确定所有3个集合的内容。因此,MATCH子句找到与b节点相关的节点,并限制其他(可选)匹配仅考虑这些节点 - 这应该加快查询速度。 APOC函数apoc.coll.intersection用于与yszs集合相交以获取xs集合。

[EDITED]

我们不是同时执行两个COLLECT操作(在第二个可选匹配之后),而是在第一个可选匹配后立即执行第一个COLLECT操作,以便我们可以避免使用笛卡尔积。这应该可以加快查询速度并降低内存需求。

答案 1 :(得分:2)

对于那些无法访问APOC的人,这里是Sams answer

的普通Cypher版本
// Get Start Nodes
MATCH (a {n: 1}), (b {n: 2}), (c {n: 3})

// Find common nodes for ab and cb
OPTIONAL MATCH (a)-->(ab)<--(b)
OPTIONAL MATCH (c)-->(cb)<--(b)

// Aggregate common nodes of ab and cb
WITH a, b, c, COLLECT(ab) AS ab, COLLECT(cb) AS cb

// Return with additional Aggregate of intersection of the lists ab and cb
RETURN a, b, c, filter(n in ab WHERE n IN cb) as abc, ab, cb