简体   繁体   English

Cypher - 具有可选匹配的聚合

[英]Cypher - Aggregation with optional match

I have the following node structure in database:我在数据库中有以下节点结构:

Artifact {id:'art1'}
|ArtifactProperty {key:'prop1_1', value:1}
|ArtifactProperty {key:'prop1_2', value:2}
=Artifact {id:'art1_1'}
=|ArtifactProperty {key:'prop1_1_1', value:1}
=|ArtifactProperty {key:'prop1_1_2', value:2}
==Artifact {id:'art1_1_1'}
==|ArtifactProperty {key:'prop1_1_1_1', value:1}
==|ArtifactProperty {key:'prop1_1_1_2', value:2}
==Artifact {id:'art1_1_2'}
==|ArtifactProperty {key:'prop1_1_2_1', value:1}
==|ArtifactProperty {key:'prop1_1_2_2', value:2}
==Artifact {id:'art1_1_3'}
==|ArtifactProperty {key:'prop1_1_3_1', value:1}
==|ArtifactProperty {key:'prop1_1_3_2', value:2}

Where an Artifact is a node that can be related to other Artifact nodes via a CURRENT relation and/or ArtifactProperties also via a CURRENT relation.其中 Artifact 是可以通过 CURRENT 关系和/或 ArtifactProperties 也通过 CURRENT 关系与其他 Artifact 节点相关的节点。 The CURRENT relation holds the id of the root CURRENT 关系持有根的 id

My goal is to fetch all artifacts whith its children and properties.我的目标是获取所有带有子项和属性的工件。

The following request:以下请求:

MATCH (a:Artifact)-[:CURRENT {root: 'art1'}]->(c:ArtifactProperty)
OPTIONAL MATCH (a:Artifact)-[:CURRENT {root: 'art1'}]->(b:Artifact) 
WITH a {.id, children: collect(b {.id}), properties: collect(c {.key, .value})} as mapped
return mapped.id, mapped.children, mapped.properties

Provides the following result:提供以下结果:

╒═══════════╤══════════════════════════════════════════════════════════════════════╤══════════════════════════════════════════════════════════════════════╕
│"mapped.id"│"mapped.children"                                                     │"mapped.properties"                                                   │
╞═══════════╪══════════════════════════════════════════════════════════════════════╪══════════════════════════════════════════════════════════════════════╡
│"art1_1"   │[{"id":"art1_1_3"},{"id":"art1_1_2"},{"id":"art1_1_1"},{"id":"art1_1_3│[{"value":1.0,"key":"prop_1_1_1"},{"value":1.0,"key":"prop_1_1_1"},{"v│
│           │"},{"id":"art1_1_2"},{"id":"art1_1_1"}]                               │alue":1.0,"key":"prop_1_1_1"},{"value":2.0,"key":"prop_1_1_2"},{"value│
│           │                                                                      │":2.0,"key":"prop_1_1_2"},{"value":2.0,"key":"prop_1_1_2"}]           │
├───────────┼──────────────────────────────────────────────────────────────────────┼──────────────────────────────────────────────────────────────────────┤
│"art1_1_1" │[]                                                                    │[{"value":1.0,"key":"prop_1_1_1_1"},{"value":2.0,"key":"prop_1_1_1_2"}│
│           │                                                                      │]                                                                     │
├───────────┼──────────────────────────────────────────────────────────────────────┼──────────────────────────────────────────────────────────────────────┤
│"art1"     │[{"id":"art1_1"},{"id":"art1_1"}]                                     │[{"value":1.0,"key":"prop_1_1"},{"value":2.0,"key":"prop_1_2"}]       │
├───────────┼──────────────────────────────────────────────────────────────────────┼──────────────────────────────────────────────────────────────────────┤
│"art1_1_2" │[]                                                                    │[{"value":1.0,"key":"prop_1_1_2_1"},{"value":2.0,"key":"prop_1_1_2_2"}│
│           │                                                                      │]                                                                     │
├───────────┼──────────────────────────────────────────────────────────────────────┼──────────────────────────────────────────────────────────────────────┤
│"art1_1_3" │[]                                                                    │[{"value":1.0,"key":"prop_1_1_2_1"},{"value":2.0,"key":"prop_1_1_2_2"}│
│           │                                                                      │]

The issue is my results are repeated for Artefacts with children (properties and children fields contain twice the same result).问题是我的结果重复了带有子项的人工制品(属性和子项字段包含两次相同的结果)。

There is probably a better way to perform this aggregation than to do an OPTIONAL MATCH so let me know if I did not pick the best option.执行此聚合可能有比执行 OPTIONAL MATCH 更好的方法,所以如果我没有选择最佳选项,请告诉我。

EDIT: This is the result I am trying to get, note that each child and property appear only once:编辑:这是我想要得到的结果,请注意每个孩子和属性只出现一次:

╒═══════════╤══════════════════════════════════════════════════════════════════════╤══════════════════════════════════════════════════════════════════════╕
│"mapped.id"│"mapped.children"                                                     │"mapped.properties"                                                   │
╞═══════════╪══════════════════════════════════════════════════════════════════════╪══════════════════════════════════════════════════════════════════════╡
│"art1_1"   │[{"id":"art1_1_3"},{"id":"art1_1_2"},{"id":"art1_1_1"}]               │[{"value":1.0,"key":"prop_1_1_1"},{"value":2.0,"key":"prop_1_1_2"}    │
│           │                                                                      │                                                                      │
│           │                                                                      │                                                                      │
├───────────┼──────────────────────────────────────────────────────────────────────┼──────────────────────────────────────────────────────────────────────┤
│"art1_1_1" │[]                                                                    │[{"value":1.0,"key":"prop_1_1_1_1"},{"value":2.0,"key":"prop_1_1_1_2"}│
│           │                                                                      │]                                                                     │
├───────────┼──────────────────────────────────────────────────────────────────────┼──────────────────────────────────────────────────────────────────────┤
│"art1"     │[{"id":"art1_1"}]                                                     │[{"value":1.0,"key":"prop_1_1"},{"value":2.0,"key":"prop_1_2"}]       │
├───────────┼──────────────────────────────────────────────────────────────────────┼──────────────────────────────────────────────────────────────────────┤
│"art1_1_2" │[]                                                                    │[{"value":1.0,"key":"prop_1_1_2_1"},{"value":2.0,"key":"prop_1_1_2_2"}│
│           │                                                                      │]                                                                     │
├───────────┼──────────────────────────────────────────────────────────────────────┼──────────────────────────────────────────────────────────────────────┤
│"art1_1_3" │[]                                                                    │[{"value":1.0,"key":"prop_1_1_2_1"},{"value":2.0,"key":"prop_1_1_2_2"}│
│           │                                                                      │]

Try to use DISTINCT :尝试使用DISTINCT

MATCH (a:Artifact)-[:CURRENT {root: 'art1'}]->(c:ArtifactProperty)
OPTIONAL MATCH (a:Artifact)-[:CURRENT {root: 'art1'}]->(b:Artifact) 
WITH a {
  .id, 
  children: collect(DISTINCT b {.id}), 
  properties: collect(DISTINCT c {.key, .value})
} AS mapped
RETURN mapped.id, mapped.children, mapped.properties

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM