2017-03-07 128 views
0

我目前开始使用Neo4J,它是查询语言密码。 我有一个多重查询,遵循相同的模式。优化Cypher查询

我做一个SQL的数据库和Neo4j的之间的一些比较。

在我的Neo4j Datababase我HABE一种类型的标签(人)和一个类型的关系(友谊)。该人拥有个人身份,姓名,电子邮件,电话。 现在我想拥有这个朋友的第n个学位。我也想过滤出那些也是较低学位朋友的人。 例如,如果我想搜索朋友3度,我想过滤掉那些也是朋友第一和/或第二度的朋友。

这里我的查询类型:

MATCH (me:person {personID:'1'})-[:FRIENDSHIP*3]-(friends:person) 
WHERE NOT (me:person)-[:FRIENDSHIP]-(friends:person) 
AND NOT (me:person)-[:FRIENDSHIP*2]-(friends:person) 
RETURN COUNT(DISTINCT friends); 

我发现类似的东西的地方。

此查询适用。

我的问题是,查询的这种模式是非常慢,如果我搜索了更高程度的友谊和/或如果人数变得更加。

所以,我真的很感激它,如果somemone可以帮助我优化这个。

回答

1

如果你只是想处理的3深处,这应该返回是3度走,但不也小于3度走不同的节点:

MATCH (me:person {personID:'1'})-[:FRIENDSHIP]-(f1:person)-[:FRIENDSHIP]-(f2:person)-[:FRIENDSHIP]-(f3:person) 
RETURN apoc.coll.subtract(COLLECT(f3), COLLECT(f1) + COLLECT(f2) + me) AS result; 

上述查询使用APOC功能apoc.coll.subtract到从结果中删除不需要的节点。该函数还确保集合包含不同的元素。

下面的查询就比较一般了,而且应该对于任何给定的深度合作(由刚更换*后的数字)。例如,该查询将具有4的深度工作:

MATCH p=(me:person {personID:'1'})-[:FRIENDSHIP*4]-(:person) 
WITH NODES(p)[0..-1] AS priors, LAST(NODES(p)) AS candidate 
UNWIND priors AS prior 
RETURN apoc.coll.subtract(COLLECT(DISTINCT candidate), COLLECT(DISTINCT prior)) AS result; 
0

与Cypher支架的可变长度关系匹配的问题是,它在寻找到深度的所有可能路径。当您感兴趣的是某些深度的节点而不是通往它们的路径时,这可能会导致不必要的性能问题。

APOC's path expander使用'NODE_GLOBAL'uniqueness是一种更有效的手段来匹配包含深度的节点。

当使用“NODE_GLOBAL”唯一性,节点永远只能遍历期间去过一次。因此,当我们将路径扩展器的路径扩展器minLevelmaxLevel设置为相同时,结果是该级别的节点不在任何较低级别,这正是您试图获得的结果。

尝试此查询安装APOC后:

MATCH (me:person {personID:'1'}) 
CALL apoc.path.expandConfig(me, {uniqueness:'NODE_GLOBAL', minLevel:4, maxLevel:4}) YIELD path 
// a single path for each node at depth 4 but not at any lower depth 
RETURN COUNT(path) 

当然,你想你的参数输入(PERSONID,电平)当你得到机会。