我现在开始使用Neo4J,它是查询语言cypher。我有一个遵循相同模式的多个查询。
我正在做一些SQL数据库和Neo4J之间的比较。
在我的Neo4J数据库中,我有一种类型的标签(个人)和一种类型的关系(友谊)。该人有属性的personID,姓名,电子邮件,电话。现在我想拥有朋友们的第n个学位。我也想过滤掉那些也是低学历朋友的人。例如,如果我想搜索朋友3度,我想过滤掉那些也是第一和/或第二度朋友的FOr。
下面是我的查询类型:
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);我在某处发现了类似的东西。
这个查询是有效的。
我的问题是,如果我搜索更高程度的友谊和/或如果人数变得更多,这种查询模式会变得很慢。
所以,如果有人能帮我优化一下,我会非常感激的。
发布于 2017-03-08 05:15:07
如果您只想处理深度为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;发布于 2017-03-08 17:05:50
Cypher的可变长度关系匹配的问题是,它正在寻找到达该深度的所有可能路径。当您感兴趣的只是某些深度的节点而不是到它们的路径时,这可能会导致不必要的性能问题。
使用'NODE_GLOBAL‘uniqueness的APOC's path expander是在包含性深度匹配节点的更有效的方法。
当使用'NODE_GLOBAL‘唯一性时,节点在遍历期间只被访问一次。因此,当我们将路径扩展器的minLevel和maxLevel设置为相同时,结果是该级别上的节点在任何较低级别上都不存在,这正是您试图获得的结果。
在安装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,level)。
https://stackoverflow.com/questions/42656954
复制相似问题