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

时间:2017-05-05 18:44:13

标签: neo4j cypher

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

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

单独获取节点'n'然后在单独调用中获取路径会更高效,还是应该执行返回'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

1 个答案:

答案 0 :(得分: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;