Neo4j Cypher嵌套的Collect函数

15

想象一下一个包含用户、相册和照片的相册架构:

User -[owns]-> Album -[contains]-> Photo

我能否进行嵌套收集以获取相册中的照片,以及用户中的相册?我想要类似以下结果的内容:

{ "users": [
    { "name": "roger dodger",
      "albums": [
        { "album": "album1",
          "photos": [
            {"url": "photo1.jpg"},
            {"url": "photo2.jpg"}
          ]
        }
      ]
    }
  ]
}

这看起来很接近,但我无法修改它以适应我的需求:Cypher中的嵌套has_many关系 (问题可能是因为Neo4j 2.0 Web控制台不支持该示例中的JSON语法?)

1个回答

29

试试这个查询:

MATCH (a:USER)-[:owns]->(b:ALBUM)-[:CONTAINS]->(c:PHOTO)
WITH a,b,{url: c.name} as c_photos
WITH a,{album: b.name , photos: collect(c_photos)} as b_albums
WITH {name: a.name, albums: collect(b_albums)} as a_users
RETURN {users: collect(a_users)}

编辑

要获取节点的所有属性,可以使用节点的字符串表示形式,然后使用Java等单独解析它。

MATCH (a:User)
WITH {user: str(a)} as users
RETURN {users: collect(users)}

太好了!有两个问题:1)你是从哪里学到这个自定义的JSON密码语法的 - 你能给我指出文档吗?2)是否有一种方法可以在不显式分配JSON字段到节点属性的情况下包含节点的所有属性? - Bob B
第一个问题:我在你分享的那个stackoverflow链接中看到了这种语法。第二个问题:目前没有办法列出节点的所有属性进行迭代。但是有一个解决方法是获取节点的字符串表示形式。请查看我的编辑。 - Sumeet Sharma
为了收集节点的所有属性,您可以只收集完整节点,因此将 ...{ album: b.name } 更改为 { album: b } 应该就可以了。您可以对其他内容执行相同的操作,但我个人更喜欢使用需要使用的道具的较长查询,而不是返回所有内容(返回的数据较少)。 - bart
救命稻草!在阅读这个答案之前,我一直在做疯狂的事情。感谢Sumeet,顺便问一下第二部分,什么是str()函数,我试过了,但似乎该函数已被删除? - Anil Maharjan
节点的字符串表示形式。这是一个相当古老的答案,可能已被其他功能移除/替换。 - Sumeet Sharma
这和使用 apoc.convert.toTree 是一样的吗? - Redink

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接