2017-05-05 58 views
0

我需要根据关系返回一个节点及与其相关的所有节点。查询的一个例子是这样的:从Neo4j得到结果​​的最有效的方法

MATCH (n) where id(n)= {neo_id} 
OPTIONAL MATCH p=(n)-[:OWNS]->(q) 

它会更有效地获取自身的节点“N”,然后获得一个单独的呼叫路径,或者我应该做一个callthat回报“N”和'p'。

Addt。信息:我必须为多重关系做到这一点,我注意到每次添加关系时,所有路径之间的组合会导致性能下降。例如:

MATCH (n) where id(n)= {neo_id} 
OPTIONAL MATCH p=(n)-[:OWNS]->(q:Something) 
OPTIONAL MATCH o=(n)-[:USES]->(r:SomethingElse) 
. 
. 
. 
OPTIONAL MATCH l=(n)-[:LOCATED_IN]->(r:NthSomethingElse) 
RETURN n, p, o,..., l 

//Call 1 
MATCH (n) where id(n)= {neo_id} 
RETURN n 

//Call 2 
MATCH (n) where id(n)= {neo_id} 
OPTIONAL MATCH p=(n)-[:OWNS]->(q:Something) 
RETURN p 

//Call 3 
MATCH (n) where id(n)= {neo_id} 
OPTIONAL MATCH o=(n)-[:USES]->(r:SomethingElse) 
RETURN o 
. 
. 
. 
//Call nth 
MATCH (n) where id(n)= {neo_id} 
OPTIONAL MATCH l=(n)-[:LOCATED_IN]->(r:NthSomethingElse) 
RETURN l 

回答

2

如果你总是希望得到n(如果存在的话),即使它没有关系,那么你的第一个查询确实是这样做的唯一途径。如果你不想这样做,那么将2个子句合并为1可能对性能影响不大。

每当您添加另一个MATCH时,您会注意到减速的原因是因为“笛卡尔产品”。即:如果MATCHOPTIONAL MATCH子句将“正常”生成N行数据,但同一查询中的先前子句已生成M行数据,则实际生成的行数将为M * N。所以,每个额外的MATCH都对数据行数有乘数效应。

根据您的使用情况,您可以通过对所有(或希望最多)MATCH子句的结果使用聚合来避免笛卡尔积,这可以将N变为1(或其他较小数)。例如:

MATCH (n) where id(n)= {neo_id} 
OPTIONAL MATCH p=(n)-[:OWNS]->(:Something) 
WITH n, COLLECT(p) AS owns 
OPTIONAL MATCH o=(n)-[:USES]->(:SomethingElse) 
WITH n, owns, COLLECT(o) AS uses 
OPTIONAL MATCH l=(n)-[:LOCATED_IN]->(:NthSomethingElse) 
WITH n, owns, uses, COLLECT(l) AS located_in 
RETURN n, owns, uses, located_in; 
+0

完美!这很有道理。 –

相关问题