neo4j与单向关系
我是新来的neo4j与单向关系,neo4j,Neo4j,我是新来的neo4j。我刚刚读了一些关于这个工具的信息,在Ubuntu上安装了它,并进行了一系列的查询。在这一刻,我必须承认,我真的很喜欢它。然而,有些东西(我认为非常简单和直观),我不知道如何实现。因此,我创建了三个节点,如下所示: CREATE (n:Object {id:1}) RETURN n CREATE (n:Object {id:2}) RETURN n CREATE (n:Object {id:3}) RETURN n 我在他们之间建立了一种等级关系: MATCH (a:Obj
neo4j
。我刚刚读了一些关于这个工具的信息,在Ubuntu上安装了它,并进行了一系列的查询。在这一刻,我必须承认,我真的很喜欢它。然而,有些东西(我认为非常简单和直观),我不知道如何实现。因此,我创建了三个节点,如下所示:
CREATE (n:Object {id:1}) RETURN n
CREATE (n:Object {id:2}) RETURN n
CREATE (n:Object {id:3}) RETURN n
我在他们之间建立了一种等级关系:
MATCH (a:Object {id:1}), (b:Object {id:2}) CREATE (a)-[:PARENT]->(b)
MATCH (a:Object {id:2}), (b:Object {id:3}) CREATE (a)-[:PARENT]->(b)
因此,我认为这个简单的层次结构应该如下所示:
(id:1)
-> (id:2)
-> (id:3)
我现在想要的是从任何节点获取路径。例如,如果我想从节点(id:2)获得一个路径,我将获得(id:2)->(id:3)。如果我想从节点(id:1)获取路径,我将获取(id:1)->(id:2)->(id:3)。我尝试了以下查询:
MATCH (n:Object {id:2})-[*]-(children) return n, children
我认为它应该返回一个路径(id:2)->(id:3),但出乎意料地(仅对我而言)它返回(id:1)->(id:2)->(id:3)。那么,我做错了什么,应该使用什么样的查询?neo4j中的所有关系都是定向的。当你说
(n)-[:foo]->(m)
时,这种关系只有一种方式,从n
到m
现在需要注意的是,你可以从两个方面来引导关系。这并不是说关系是双向的,它从来都不是——它只意味着你可以从任何一个方向来看待它
编写此查询时:(n:Object{id:2})-[*]-(children)
您没有在该关系上放置箭头,因此children
可以引用相关节点的下游或上游
换句话说,说(n)-[:test](m)
与匹配两个(n)(m)
是一样的
因此children
可以引用ID1对象或ID2对象。只返回children
直接回答你的问题,
你的问题
MATCH (n:Object {id:2})-[*]-(children) return n, children
不仅将来自(n{id:2})
的关系匹配到其子级,而且还将来自其父级的关系匹配到(n{id:2})
您需要另外指定您想要的方向。这将返回您期望的结果:
MATCH (n:Object {id:2})-[*]->(children) return n, children
与示例有关的问题 我想回答你关于单向和双向关系的评论,但是让我们首先用这个例子解决几个问题 使用正确的标签 让我们回顾一下您的示例:
(:Object {id:1})-[:PARENT]->(:Object {id:2})-[:PARENT]->(:Object {id:3})
使用像:Object
,:Node
,:Thing
这样的标签是没有意义的。如果你真的不在乎,就不要用标签
在这种情况下,看起来我们谈论的是人,虽然它也很容易是主板和子板,或其他东西
让我们使用人而不是对象:
(:Person {id:1})-[:PARENT]->(:Person {id:2})-[:PARENT]->(:Person {id:3})
Neo4j中的IDs
Neo4j存储每个节点和关系的自己的ID。您可以使用id(nodeOrRelationship)
检索这些id,并使用WHERE
子句按id访问这些id,或者将它们指定为匹配的起点START n=node(2)MATCH(n)-[*]-(children)返回n,children
相当于原始查询MATCH(n:Object{id:2})-[*]-(children)返回n,children
让我们存储一些关于节点的有用信息,比如名称,而不是ID:
(:Person {name:'Bob'})-[:PARENT]->(:Person {name:'Mary'})-[:PARENT]->(:Person {name:'Tom'})
关系模糊
最后,让我们消除关系的歧义。PARENT
的意思是“是的父母”还是“有这个父母”?你可能很清楚你指的是哪一个,但不熟悉你的系统的人可能会有相反的解释
我想你的意思是“是孩子的父母”,所以让我们说清楚:
(:Person {name:'Bob'})-[:PARENT_OF]->(:Person {name:'Mary'})-[:PARENT_OF]->(:Person {name:'Tom'})
有关Neo4j中单向和双向关系的更多信息 现在,我们已经用这个例子解决了一些基本问题,让我们讨论一下Neo4j和一般图形中关系的方向性 在本例中,我们可以通过几种方式表达关系。让我们看几个 无向/双向关系 为了便于讨论,让我们抽象出上面使用的父关系:
(bob)-[:KIN]-(mary)-[:KIN]-(tom)
这里的关系KIN
表明他们是相关的,但我们不知道到底谁是谁的父母。汤姆是玛丽的孩子,还是玛丽的孩子
请注意,我没有使用任何箭头。在上面的图伪代码中,KIN
关系是双向或无向关系
然而,Neo4j中的关系总是有方向性的。如果KIN
关系确实是您想要跟踪事物的方式,那么您应该创建一个方向关系,但总是忽略MATCH
查询中的方向,例如MATCH(a)-[:KIN]-(b)
而不是MATCH(a)-[:KIN]->(b)
但是,亲属关系真的是存储这些信息的最佳方式吗?我们可以让它更具体。让我们回到前面使用的关系的父关系
定向/单向关系
回到例子。我们知道鲍勃是玛丽的父母,玛丽是汤姆的父母:
(bob)-[:PARENT_OF]->(mary)-[:PARENT_OF]->(tom)
显然,其推论是:
(bob)<-[:CHILD_OF]-(mary)<-[:CHILD_OF]-(tom)
那么,我们是否应该继续在(bob)、(mary)和(tom)节点之间创建的父节点和的子节点
答案是否定的。我们可以从这些关系中选择一种,无论哪种关系最符合想法,我们仍然能够从两个方面进行搜索
仅使用关系的:PARENT\u,我们就可以
MATCH (mary {name:'Mary'})-[:PARENT_OF]->(children) RETURN children
找到孩子,或者
MATCH (mary {name:'Mary'})<-[:PARENT_OF]-(parents) RETURN parents
MATCH(mary{name:'mary'})我在这里和那里看到了很多评论,我真想知道为什么人们会问如何建立双向关系。然而,我不需要做任何事情来建立这种双向关系。但与此同时,我不知道如何建立单向关系。好像我把它弄坏了。在上一个查询中,我将-
替换为->
:匹配(n:Object{id:2})-[*]->(子对象)
MATCH (mary {name:'Mary'})<-[:PARENT_OF]-(parents) RETURN parents