如何在neo4j cypher中按节点标签过滤结果?

时间:2016-09-27 19:51:04

标签: neo4j cypher

我有一个图表数据库,用于绘制建筑物和公交车站之间的连接,其中图表包含其他连接件,如道路和交叉路口(在许多节点类型中)。

我想弄清楚的是如何过滤路径以仅返回特定的节点类型。我有两个与我目前正在努力解决的相关问题。

问题1:如何沿路径返回节点标签?

似乎合乎逻辑的第一步是确定沿路径发生的类型节点。

我尝试了以下内容:

MATCH p=(a:Building)­-[:CONNECTED_TO*..5]­-(b:Bus) 
WITH nodes(p) AS nodes 
RETURN DISTINCT labels(nodes);

但是,我收到类型异常错误,标签()需要类型为node而不是Collection的数据。我想动态地知道路径上有哪些类型的节点,这样我最终可以过滤我的路径。

问题2:如何在路径中返回与我在第一步中识别的标签匹配的节点子集?

说我发现在(a:Building)(d1:Bus)以及(d2:Bus)之间我可以找到(:Intersection)个节点和(:Street)个节点。

这是我的图表的简化模型:

(a:Building)­­--(:Street)­--­(:Street)--­­(b1:Bus) 
             \­­(:Street)--­­(:Intersection)­­--(:Street)--­­(b2:Bus)

我已经编写了一个MATCH语句,用于查找(:Building)(:Bus)个节点之间的所有可能路径。接下来我需要做什么来过滤以选择性地返回街道节点?

MATCH p=(a:Building)-[r:CONNECTED_TO*]-(b:Bus)
  // Insert logic to only return (:Street) nodes from p

非常感谢任何关于此的指导!

2 个答案:

答案 0 :(得分:3)

  1. 要在匹配路径中获取不同的标签:

    MATCH p=(a:Building)-[:CONNECTED_TO*..5]-(b:Bus)
    WITH NODES(p) AS nodes
    UNWIND nodes AS n
    WITH LABELS(n) AS ls
    UNWIND ls AS label
    RETURN DISTINCT label;
    
  2. 返回具有Street标签的节点。

    MATCH p=(a:Building)-[r:CONNECTED_TO*]-(b:Bus)
    WITH NODES(p) AS nodes
    UNWIND nodes AS n
    WITH n
    WHERE 'Street' IN LABELS(n)
    RETURN n;
    

答案 1 :(得分:0)

Cyber​​sam的答案很好,但他们的输出只是一列标签......你完全丢失了路径信息。因此,如果从:Building到a:Bus有多条路径,第一个查询将仅输出所有模式中所有节点中的所有标签,并且您无法分辨存在多少路径,并且由于丢失了路径信息,因此您无法告诉某些路径中的标签,但不是其他路径,或某些路径之间的共同点。

同样,第二个查询会丢失路径信息,因此如果有多条路径使用不同的街道从:建筑物到:公共汽车,cybersam的查询将返回所有路径中涉及的所有街道。它可以输出图表中的所有街道,这似乎没什么用处。

您需要保存路径信息的查询。

对于1,在每个路径上的节点上找到不同的标签,我将提供此查询:

MATCH p=(:Building)-[:CONNECTED_TO*..5]-(:Bus)
WITH NODES(p) AS nodes
WITH REDUCE(myLabels = [], node in nodes | myLabels + labels(node)) as myLabels
RETURN DISTINCT myLabels

对于2,此查询保留路径信息:

MATCH p=(:Building)-[:CONNECTED_TO*..5]-(:Bus)
WITH NODES(p) AS nodes
WITH FILTER(node in nodes WHERE (node:Street)) as pathStreets
RETURN pathStreets

请注意,这些都是昂贵的操作,因为它们执行所有建筑物和所有公共汽车的笛卡尔积,如描述中的查询。我强烈建议缩小你所匹配的建筑物和公共汽车的距离,希望至少对很少或特定的建筑物来说。

我还鼓励限制你在模式中的深度。我认为图表中的许多(如果不是大多数)节点都通过以下方式连接:CONNECTED_TO关系,如果我们没有将其限制在合理的数量,那么您的查询可以找到整个图表中的每条路径,无论多久或复杂或荒谬,我认为这不是你想要的。