2017-03-31 66 views
0

我有以下查询,其中有3个MATCHES,与WITH连接,搜索3个路径。Neo4j在Cypher中通过WITH传递不同节点

MATCH (:File {name: 'A'})-[:FILE_OF]->(:Fun {name: 'B'})-->(ent:CFGEntry)-[:Flows*]->()-->(expr:CallExpr {name: 'C'})-->()-[:IS_PARENT]->(Callee {name: 'd'}) 
WITH expr, ent 

MATCH (expr)-->(:Arg {chNum: '1'})-->(id:Id) 
WITH id, ent 

MATCH (entry)-[:Flows*]->(:IdDecl)-[:Def]->(sym:Sym) 
WHERE id.name = sym.name 
RETURN id.name 

查询返回两个不同的ID和一个不同的入口,和7个不同符号。

问题是因为在第二次MATCH中我传递了“WITH ID,​​entry”和两个不同的id,两个条目实例被传递给第三个匹配而不是1,第三个运行时间不必要的匹配至少会翻倍。

我想知道如果有人知道我应该如何写这个查询来使用一个单一的条目实例。

回答

0

你最好的选择将是聚集ID,但随后你需要调整你的逻辑在相应查询的第三部分:

MATCH (:File {name: 'A'})-[:FILE_OF]->(:Fun {name: 'B'})-->(ent:CFGEntry)-[:Flows*]->()-->(expr:CallExpr {name: 'C'})-->()-[:IS_PARENT]->(Callee {name: 'd'}) 
WITH expr, ent 

MATCH (expr)-->(:Arg {chNum: '1'})-->(id:Id) 
WITH collect(id.name) as names, ent 

MATCH (entry)-[:Flows*]->(:IdDecl)-[:Def]->(sym:Sym) 
WHERE sym.name in names 
RETURN sym.name 
+0

非常感谢你。这解决了我的问题。但是更常见的问题是:您利用了以下事实:稍后我不会将id用作基于MATCH的搜索节点。如果我在以后的比赛中有MATCH(id),你如何避免这个问题(重复ent)?我们不能使用您的解决方案,因为我们无法将收集的结果(a)AS b传递给MATCH(b),因为它期望一个节点,并且我们将它传递给一个节点列表。 – Afshin

+0

你有几种选择对你开放。您可以在收集“id.name”的同一行上单独收集“id”。这将为您提供每个expr的ID集合和ID名称集合。在你必须做'匹配(b)'的地方,你可以在收集之前将集合解压回到节点行。 – InverseFalcon

+0

非常感谢。 – Afshin

相关问题