neo4j - 首选通过直接连接而不是较长路径的节点
问题描述
我的图形模型应该允许从父级继承属性到子级,并覆盖子级的继承属性。属性是附加有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]->P
和C2-[:BELONGS_TO]->P
。P
定义了一个Name
继承的属性和一个Other
不继承的属性。C1
已覆盖该Name
属性,而C2
继承该属性。
我现在想查找属于某个节点的所有相关属性:C1 的直接附加名称属性和 C2 的间接名称属性。不应为 C1 和 C2 考虑“其他”属性,因为它不是继承的。
要获取所有直接和继承的属性,我可以使用以下查询:
MATCH (c {id: "C1"})-[:HAS]->(directAttribute:Attribute), (c)-[]->(:Node)-[:HAS{inherited: true}]->(inheritedAttribute:Attribute) RETURN directAttribute, inheritedAttribute
但这显然会返回两个Name
属性,一个来自C1
和继承自P
。我们如何“更喜欢”直接附加到节点的属性而不是继承的属性,以便在这种情况下,查询只返回“直接”名称属性?
解决方案
使用节点标签来区分属性名称对于您的用例来说非常笨拙。我建议将属性名称改为属性名称。例如,name
在other
以下数据创建查询中(以及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来获取 a 的适用属性Node
(注意将“直接”属性作为第二个参数传递)。
例如,如果您将此查询用于“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}]
。
推荐阅读
- ruby-on-rails - 如何在rails中使用相同的身份验证回调对两种类型的用户进行身份验证?
- java - OpenJDK 11 错误“无法初始化加密机制”
- logging - 为什么 ariflow 登录 google cloud composer 突然出现 '[Errno -2] name or service not know' 导致的错误?
- angular - 从另一个不使用 EventEmitter() 的组件调用函数
- mysql - 将 CLOUD-SQL 连接到 Google-Data-Studio,出了什么问题?
- sql - Oracle SQL 开发人员显示以下代码的无效编号
- git - 如何在 GitKraken 上创建新提交而不是快速合并
- azure - 修改 PowerShell 脚本以更改 Outlook 的默认字体类型和大小
- javascript - 如果需要,遍历 URL 并添加/替换字符串
- angularjs - ng-view 在我的 angularJS 应用程序中没有显示任何内容