Neo4j 首选通过直接连接而不是较长路径的节点

Neo4j 首选通过直接连接而不是较长路径的节点,neo4j,cypher,graph-databases,Neo4j,Cypher,Graph Databases,我的图形模型应该允许将属性从父对象继承到子对象,并覆盖子对象上的此类继承属性。属性是附加有关系的节点 CREATE (parent:Node {id: "P"})-[:HAS {inherited: true}]->(:Attribute:Name {value: "Indirect Name"}) CREATE (parent)-[:HAS]->(:Attribute:Other {value: "Other Attribute"}) CREATE (c1:Node {id: "

我的图形模型应该允许将属性从父对象继承到子对象,并覆盖子对象上的此类继承属性。属性是附加有
关系的节点

CREATE (parent:Node {id: "P"})-[:HAS {inherited: true}]->(:Attribute:Name {value: "Indirect Name"})
CREATE (parent)-[:HAS]->(:Attribute:Other {value: "Other Attribute"})

CREATE (c1:Node {id: "C1"})-[:HAS]->(:Attribute:Name {value: "Direct Name"})
CREATE (c1)-[:BELONGS_TO]->(parent)
CREATE (c2:Node {id: "C2"})-[:BELONGS_TO]->(parent)
在本例中,我们有
C1-[:belishing_TO]->p
C2-[:belishing_TO]->p
P
定义了继承的属性
名称
,以及未继承的属性
其他
C1
覆盖了
Name
属性,而
C2
继承了该属性

现在我想查找属于某个节点的所有相关属性:C1的直接附加名称属性和C2的间接名称属性。C1和C2不应考虑“other”属性,因为它不是继承的

要获取所有直接属性和继承属性,我可以使用以下查询:

MATCH (c {id: "C1"})-[:HAS]->(directAttribute:Attribute), (c)-[]->(:Node)-[:HAS{inherited: true}]->(inheritedAttribute:Attribute) RETURN directAttribute, inheritedAttribute

但是,这显然会返回
Name
属性,即来自
C1
的属性和从
p
继承的属性。我们如何“偏好”直接附加到节点的属性而不是继承的属性,以便在这种情况下,查询只返回“直接”名称属性?

对于您的用例来说,使用节点标签来区分属性名称非常不方便。我建议将属性名改为属性名。例如,作为以下数据创建查询中的
name
other
(以及
foo
,以显示如何具有多个继承属性):

然后,您可以使用方便的APOC函数获取
节点的适用属性(注意将“direct”属性作为第二个参数传递)

例如,如果将此查询用于“C1”:

结果是:

╒═══════════╤══════════════════════════════════╕
│"c"        │"attrs"                           │
╞═══════════╪══════════════════════════════════╡
│{"id":"C1"}│{"name":"Direct Name","foo":"Bar"}│
└───────────┴──────────────────────────────────┘
对“C2”的相同查询得到以下结果:

╒═══════════╤════════════════════════════════════╕
│"c"        │"attrs"                             │
╞═══════════╪════════════════════════════════════╡
│{"id":"C2"}│{"name":"Indirect Name","foo":"Bar"}│
└───────────┴────────────────────────────────────┘

您可能还希望使用不同的关系类型(例如,
[:INHERITS]
)来代替
[:HAS{inherited:true}]

使用节点标签来区分属性名称对于您的用例来说是相当麻烦的。我建议将属性名改为属性名。例如,作为以下数据创建查询中的
name
other
(以及
foo
,以显示如何具有多个继承属性):

然后,您可以使用方便的APOC函数获取
节点的适用属性(注意将“direct”属性作为第二个参数传递)

例如,如果将此查询用于“C1”:

结果是:

╒═══════════╤══════════════════════════════════╕
│"c"        │"attrs"                           │
╞═══════════╪══════════════════════════════════╡
│{"id":"C1"}│{"name":"Direct Name","foo":"Bar"}│
└───────────┴──────────────────────────────────┘
对“C2”的相同查询得到以下结果:

╒═══════════╤════════════════════════════════════╕
│"c"        │"attrs"                             │
╞═══════════╪════════════════════════════════════╡
│{"id":"C2"}│{"name":"Indirect Name","foo":"Bar"}│
└───────────┴────────────────────────────────────┘

您可能还希望使用不同的关系类型(例如,
[:INHERITS]
)来代替
[:HAS{inherited:true}]
,谢谢,这是一个好的开始。当我将另一个“父项”添加到例如C1
(C1)-[:bellings\u to]->(P2)
时,此查询使用不同的属性集多次返回c。然后如何合并所有属性?顺便问一下:为什么标记不同类型的属性不适合这个用例?谢谢,这是一个好的开始。当我将另一个“父项”添加到例如C1
(C1)-[:bellings\u to]->(P2)
时,此查询使用不同的属性集多次返回c。然后我如何合并所有属性?顺便问一下:为什么标记不同类型的属性不适合这个用例?