简体   繁体   English

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

[英]How to filter results by node label in neo4j cypher?

I have a graph database that maps out connections between buildings and bus stations, where the graph contains other connecting pieces like roads and intersections (among many node types). 我有一个图表数据库,用于绘制建筑物和公交车站之间的连接,其中图表包含其他连接件,如道路和交叉口(在许多节点类型中)。

What I'm trying to figure out is how to filter a path down to only return specific node types. 我想弄清楚的是如何过滤路径以仅返回特定的节点类型。 I have two related questions that I'm currently struggling with. 我有两个与我目前正在努力解决的相关问题。

Question 1: How do I return the labels of nodes along a path? 问题1:如何沿路径返回节点标签?

It seems like a logical first step is to determine what type of nodes occur along the path. 似乎逻辑上的第一步是确定路径上出现的节点类型

I have tried the following: 我尝试过以下方法:

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

However, I'm getting a type exception error that labels() expects data of type node and not Collection. 但是,我得到一个类型异常错误,标签()期望数据类型为node而不是Collection。 I'd like to dynamically know what types of nodes are on my paths so that I can eventually filter my paths. 我想动态地知道我的路径上有哪些类型的节点,这样我最终可以过滤我的路径。

Question 2: How can I return a subset of the nodes in a path that match a label I identified in the first step? 问题2:如何在路径中返回与第一步中标识的标签匹配的节点子集?

Say I found that that between (a:Building) and (d1:Bus) and (d2:Bus) I can expect to find (:Intersection) nodes and (:Street) nodes. 假设我发现在(a:Building)(d1:Bus)(d2:Bus)我可以找到(:Intersection)节点和(:Street)节点。

This is a simplified model of my graph: 这是我的图表的简化模型:

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

I've written a MATCH statement that would look for all possible paths between (:Building) and (:Bus) nodes. 我编写了一个MATCH语句,用于查找(:Building)(:Bus)节点之间的所有可能路径。 What would I need to do next to filter to selectively return the Street nodes? 接下来我需要做什么来选择性地返回街道节点?

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

Any guidance on this would be greatly appreciated! 任何有关这方面的指导将不胜感激!

  1. To get the distinct labels along matching paths: 要在匹配路径中获取不同的标签:

     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. To return the nodes that have the Street 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; 

Cybersam's answers are good, but their output is simply a column of labels...you lose the path information completely. Cyber​​sam的答案很好,但他们的输出只是一列标签......你完全丢失了路径信息。 So if there are multiple paths from a :Building to a :Bus, the first query will only output all labels in all nodes in all patterns, and you can't tell how many paths exist, and since you lose path information, you cannot tell what labels are in some paths but not others, or common between some paths. 因此,如果从:Building到a:Bus有多条路径,第一个查询将仅输出所有模式中所有节点中的所有标签,并且您无法分辨存在多少路径,并且由于丢失了路径信息,因此您无法告诉某些路径中的标签是什么,而不是其他路径,或某些路径之间的共同点。

Likewise, the second query loses path information, so if there are multiple paths using different streets to get from a :Building to a :Bus, cybersam's query will return all streets involved in all paths. 同样,第二个查询丢失路径信息,因此如果有多条路径使用不同的街道从:建筑物到:公共汽车,cybersam的查询将返回所有路径中涉及的所有街道。 It is possible for it to output all streets in your graph, which doesn't seem very useful. 它可以输出图表中的所有街道,这似乎不是很有用。

You need queries that preserve path information. 您需要保留路径信息的查询。

For 1, finding the distinct labels on nodes on each path I would offer this query: 对于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

For 2, this query preserves path information: 对于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

Note that these are both expensive operations, as they perform a cartesian product of all buildings and all busses, as in the queries in your description. 请注意,这些都是昂贵的操作,因为它们执行所有建筑物和所有公共汽车的笛卡尔积,如描述中的查询。 I highly recommend narrowing down the buildings and busses you're matching upon, hopefully to very few or specific buildings at least. 我强烈建议缩小你所匹配的建筑物和公共汽车,希望至少对很少或特定的建筑物。

I also encourage limiting how deep you're looking in your pattern. 我也鼓励限制你对你的模式的深度。 I get the idea that many, if not most, of your nodes in your graph are connected by :CONNECTED_TO relationships, and if we don't cap that to a reasonable amount, your query could be finding every single path through your entire graph, no matter how long or convoluted or nonsensical, and I don't think that's what you want. 我认为图表中的许多(如果不是大多数)节点都通过以下方式连接:CONNECTED_TO关系,如果我们没有将其限制在合理的数量,那么您的查询可以找到整个图表中的每条路径,无论多久或复杂或荒谬,我都不认为这就是你想要的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM