我有一个图表数据库,用于绘制建筑物和公交车站之间的连接,其中图表包含其他连接件,如道路和交叉路口(在许多节点类型中)。
我想弄清楚的是如何过滤路径以仅返回特定的节点类型。我有两个与我目前正在努力解决的相关问题。
问题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
非常感谢任何关于此的指导!
答案 0 :(得分:3)
要在匹配路径中获取不同的标签:
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;
返回具有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)
Cybersam的答案很好,但他们的输出只是一列标签......你完全丢失了路径信息。因此,如果从: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关系,如果我们没有将其限制在合理的数量,那么您的查询可以找到整个图表中的每条路径,无论多久或复杂或荒谬,我认为这不是你想要的。