Neo4J / Cypher Filter节点基于多种关系

时间:2016-09-21 21:28:43

标签: neo4j cypher

使用Neo4J和Cypher:

根据下图,我希望能够从节点'A'开始,并获得与'A'具有'ChildOf'关系的所有孩子,但不是'InactiveChildOf'关系。所以,在这个例子中,我会找回A,C和G.此外,一个节点可以获得一个新的父节点(图中的'H'),如果我要求'H'的子节点,我应该得到B, D和E.

我试过了

match (p:Item{name:'A'}) -[:ChildOf*]-(c:Item) where NOT (p)-[:InactiveChildOf]-(c) return p,c

然而,

也会返回D和E.

也尝试过:

match (p:Item{name:'A'}) -[rels*]-(c:Item) where None (r in rels where type(r) = 'InactiveChildOf') return p,c

但这会全部归还。

希望这对Neo4J来说很容易,我只是遗漏了一些明显的东西。感谢帮助!

Parent/Child diagram

示例数据:MERGE (a:Item {name:'A'}) MERGE (b:Item {name:'B'}) MERGE (c:Item {name:'C'}) MERGE (d:Item {name:'D'}) MERGE (e:Item {name:'E'}) MERGE (f:Item {name:'F'}) MERGE (g:Item {name:'G'}) MERGE (h:Item {name:'H'}) MERGE (b)-[:ChildOf]->(a) MERGE (b)- [:InactiveChildOf] ->(a) MERGE (c)-[:ChildOf]->(a) MERGE (d)-[:ChildOf]->(b) MERGE (e)-[:ChildOf]->(b) MERGE (f)-[:ChildOf]->(c) MERGE (f)- [:InactiveChildOf] ->(c) MERGE (g)-[:ChildOf]->(c) MERGE (b)-[:ChildOf]->(h)

注意,我知道我可以简单地在ChildOf关系中添加“isActive”属性或删除关系,但我正在探索选项并试图了解这个概念是否有用。

2 个答案:

答案 0 :(得分:4)

通过阅读和检查图表,如果我错了,请更正我,但cypher查询的实际文本表示应该是

  

在A路径中找到节点,该路径中的所有节点都不能有传出   InactiveChildOf关系。

所以,在Cypher中,它将是:

MATCH p=(i:Item {name:"A"})<-[:ChildOf*]-(x)
WHERE NONE( x IN nodes(p) WHERE (x)-[:InactiveChildOf]->() )
UNWIND nodes(p) AS n
RETURN distinct n

返回

enter image description here

答案 1 :(得分:4)

如果查询解释为:查找所有节点,通过InactiveChildOf与前一节点无关的节点的路径,请求可能是这样的:

match path = (p:Item{name:'A'})<-[:ChildOf*]-(c:Item)
with nodes(path) as nds
unwind range(0,size(nds)-2) as i
with nds, 
     nds[i] as i1, 
     nds[i+1] as i2 
     where not (i1)-[:InactiveChildOf]-(i2)
with nds, 
     count(i1) as test 
     where test = size(nds)-1
return head(nds), 
       last(nds)

更新:我认为此版本更好(请检查两个节点之间是否存在至少包含一种非活动关系类型的路径):

match path = (p:Item {name:'A'})<-[:ChildOf|InactiveChildOf*]-(c)
with p, c, 
     collect( filter( r in rels(path) 
                      where type(r) = 'InactiveChildOf'
              ) 
     ) as test
          where all( t in test where size(t) = 0 )
return p, c