从Neo4j获得结果的最有效方法

从Neo4j获得结果的最有效方法,neo4j,cypher,Neo4j,Cypher,我需要返回一个节点以及基于关系与之关联的所有节点。查询的示例如下: MATCH (n) where id(n)= {neo_id} OPTIONAL MATCH p=(n)-[:OWNS]->(q) 单独获取节点“n”然后在单独的调用中获取路径会更有效吗,还是应该执行返回“n”和“p”的调用 地址。信息:我必须对多个关系执行此操作,我注意到每次添加关系时,所有路径之间的组合都会导致性能下降。例如: MATCH (n) where id(n)= {neo_id} OPTIONAL MATC

我需要返回一个节点以及基于关系与之关联的所有节点。查询的示例如下:

MATCH (n) where id(n)= {neo_id}
OPTIONAL MATCH p=(n)-[:OWNS]->(q)
单独获取节点“n”然后在单独的调用中获取路径会更有效吗,还是应该执行返回“n”和“p”的调用

地址。信息:我必须对多个关系执行此操作,我注意到每次添加关系时,所有路径之间的组合都会导致性能下降。例如:

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


如果您总是想获取
n
(如果存在),即使它没有关系,那么您的第一个查询实际上是实现这一点的唯一方法。如果您不希望这样,那么将2个子句合并为1可能对性能影响不大

每次添加另一个
MATCH
时,您都会注意到速度减慢的原因是“笛卡尔积”。也就是说:如果一个
MATCH
OPTIONAL 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;

如果您总是想获取
n
(如果存在),即使它没有关系,那么您的第一个查询实际上是实现这一点的唯一方法。如果您不希望这样,那么将2个子句合并为1可能对性能影响不大

每次添加另一个
MATCH
时,您都会注意到速度减慢的原因是“笛卡尔积”。也就是说:如果一个
MATCH
OPTIONAL 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;

完美的这很有道理。太好了!这很有道理。