首选节点通过长路径直接连接

问题描述 投票:0回答:1

我的图形模型应允许从父级继承到子级的属性,并在子级上覆盖此类继承的属性。属性是以HAS关系附加的节点。

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-[:BELONGS_TO]->PC2-[:BELONGS_TO]->PP定义了继承的属性Name和未继承的属性OtherC1覆盖了Name属性,而C2继承了该属性。

example graph

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

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

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

但是显然,这将同时返回Name属性,C1属性和P继承属性。我们该如何“偏爱”直接附加到继承节点上而不是继承节点上的属性,以便在这种情况下,查询只能返回“直接”名称属性?

neo4j cypher graph-databases
1个回答
1
投票

使用节点标签在属性名称之间进行区分对于您的用例而言非常笨拙。我建议将属性名称改为属性名称。例如,在以下数据创建查询中为nameother(以及foo,以显示如何具有多个继承的属性):

CREATE (parent:Node {id: "P"})-[:HAS {inherited: true}]->(:Attribute {name: "Indirect Name", foo: "Bar"})
CREATE (parent)-[:HAS]->(:Attribute {other: "Other Attribute"})

CREATE (c1:Node {id: "C1"})-[:HAS]->(:Attribute {name: "Direct Name"})
CREATE (c1)-[:BELONGS_TO]->(parent)
CREATE (c2:Node {id: "C2"})-[:BELONGS_TO]->(parent)

然后,您可以使用方便的APOC功能apoc.map.merge获取“ C1”的适用属性。

例如,此查询:

MATCH (c:Node {id: "C1"})
OPTIONAL MATCH (c)-[:HAS]->(da:Attribute)
OPTIONAL MATCH (c)-[:BELONGS_TO]->()-[:HAS {inherited: true}]->(ia:Attribute)
RETURN c, apoc.map.merge(ia, da) AS attrs

获得此结果:

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

对“ C2”的相同查询将得到以下结果:

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

您可能还想使用其他关系类型(例如[:INHERITS])代替[:HAS {inherited: true}]

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.