除一个节点外的最短路径

时间:2019-02-27 17:08:05

标签: neo4j cypher shortest-path

我正在对电影数据库进行查询,以检查n个节点之间的最短路径。在这个简化的示例中,我们希望两部电影之间的所有最短路径:

match p=allShortestPaths((n)-[*]-(m)) where id(n) = 87 and id(m) = 121 return p;

all

现在,我想拥有不包含Keanu Reeves的所有最短路径。 我尝试过:

match p=allShortestPaths((n)-[*]-(m)) where id(n) = 87 and id(m) = 121 and NONE(n in nodes(p) where n.name = "Keanu Reeves") return p;

但是,即使我已经索引了Person的名称字段,这也需要花费很长时间才能加载。

然后尝试以下方法:

match p=allShortestPaths((n)-[*]-(m)) where id(n) = 87 and id(m) = 121 with p WHERE NONE(n in nodes(p) where n.name = "Keanu Reeves") return p;

但是,这没有给我任何结果。我以为它会返回介于两者之间没有Keanu Reeves的那些路径而误解了这一点:

(no changes, no records)

我测试了使用any()函数是否只能使那些拥有Keanu Reeves的人。效果很好:

match p=allShortestPaths((n)-[*]-(m)) where id(n) = 87 and id(m) = 121 with p WHERE ANY(n in nodes(p) where n.name = "Keanu Reeves") return p;

any()

解决此问题的最佳方法是什么?我必须说,我的生产查询比这复杂得多,但这都归结为这个问题。它必须是一种高效的解决方案。

1 个答案:

答案 0 :(得分:2)

问题是,如果路径中的节点之一不具有属性name,则整个检查都将不通过。

所以还是检查the existence of a property

match p=allShortestPaths((n)-[*]-(m)) 
where 
    n.title = 'The Replacements' and 
    m.title = 'Speed Racer' and
    NONE(n in nodes(p) where EXISTS(n.name) and n.name = "Keanu Reeves")
return p

或使用COALESCE函数:

match p=allShortestPaths((n)-[*]-(m)) 
where 
    n.title = 'The Replacements' and 
    m.title = 'Speed Racer' and
    NONE(n in nodes(p) where COALESCE(n.name, '') = "Keanu Reeves")
return p