项目树的密码
Cypher for tree of items
我有一个类别层次结构,我想使用密码查询 - 一个查询将 return 项目列表,并将它们之间的关系作为子列表。
我正在这样创建我的项目:
CREATE (C1:Category {name:"Sport"})
CREATE (C1A:Category {name:"NHL"})
CREATE (C1B:Category {name:"NBA"})
CREATE (C1C:Category {name:"NFL"})
CREATE (C1)-[:SUB_CATEGORY]->(C1A)
CREATE (C1)-[:SUB_CATEGORY]->(C1B)
CREATE (C1)-[:SUB_CATEGORY]->(C1C)
CREATE (C2:Category {name:"Music"})
CREATE (C2A:Category {name:"Rock"})
CREATE (C2B:Category {name:"Pop"})
CREATE (C2C:Category {name:"Classic"})
CREATE (C2)-[:SUB_CATEGORY]->(C2A)
CREATE (C2)-[:SUB_CATEGORY]->(C2B)
CREATE (C2)-[:SUB_CATEGORY]->(C2C)
我希望查询 return 类似于:
{categories:[{name:music,id:1,categories:[{name:rock,id:2},{name:pop,id:3}]]...{name:sport,id:10,categories:[{name:nhl...}
我可以使用它来填充用于选择类别/子类别的下拉菜单。 (此时我想在一次查询中查询整棵树,而不是一棵一棵地查询)
另一个问题(对于我想查询树的部分部分的情况):
如何获取所有主要类别(那些不是另一个类别的子类别...)
所以没有一个完美的答案...您可以 return 所有数据,但它将采用表格格式,您需要自己将其转换为分层格式:
MATCH path=(root:Category)-[:SUB_CATEGORY*1..10]->(descendent:Category)
WHERE NOT(()-[:SUB_CATEGORY]->(root))
RETURN nodes(path) AS nodes
或者,您可以通过查找所有父项和子项然后将它们与您选择的编程语言组合到内存中来减少 return 所需的数据量:
MATCH (parent:Category)-[:SUB_CATEGORY]->(child:Category)
RETURN parent, child
您还可以创建一个 Neo4j 非托管扩展(基本上是 Neo4j 数据库的插件),它可以让您为 return 编写一些 Java 代码。
关于你的最后一个问题,已经回答的差不多了,但更直接的是:
MATCH (root:Category)
WHERE NOT(()-[:SUB_CATEGORY]->(root))
RETURN root
编辑:
我刚刚意识到你可能没有任意深入的尝试。如果它只有三个级别(而且如果它始终恰好是三个级别),您可以这样做:
MATCH (root:Category)-[:SUB_CATEGORY]->(parent:Category)-[:SUB_CATEGORY]->(child:Category)
WITH root, {category: parent, children: collect(child)} AS parent_with_children
RETURN {category: root, children: collect(parent_with_children)}
我有一个类别层次结构,我想使用密码查询 - 一个查询将 return 项目列表,并将它们之间的关系作为子列表。
我正在这样创建我的项目:
CREATE (C1:Category {name:"Sport"})
CREATE (C1A:Category {name:"NHL"})
CREATE (C1B:Category {name:"NBA"})
CREATE (C1C:Category {name:"NFL"})
CREATE (C1)-[:SUB_CATEGORY]->(C1A)
CREATE (C1)-[:SUB_CATEGORY]->(C1B)
CREATE (C1)-[:SUB_CATEGORY]->(C1C)
CREATE (C2:Category {name:"Music"})
CREATE (C2A:Category {name:"Rock"})
CREATE (C2B:Category {name:"Pop"})
CREATE (C2C:Category {name:"Classic"})
CREATE (C2)-[:SUB_CATEGORY]->(C2A)
CREATE (C2)-[:SUB_CATEGORY]->(C2B)
CREATE (C2)-[:SUB_CATEGORY]->(C2C)
我希望查询 return 类似于:
{categories:[{name:music,id:1,categories:[{name:rock,id:2},{name:pop,id:3}]]...{name:sport,id:10,categories:[{name:nhl...}
我可以使用它来填充用于选择类别/子类别的下拉菜单。 (此时我想在一次查询中查询整棵树,而不是一棵一棵地查询)
另一个问题(对于我想查询树的部分部分的情况):
如何获取所有主要类别(那些不是另一个类别的子类别...)
所以没有一个完美的答案...您可以 return 所有数据,但它将采用表格格式,您需要自己将其转换为分层格式:
MATCH path=(root:Category)-[:SUB_CATEGORY*1..10]->(descendent:Category)
WHERE NOT(()-[:SUB_CATEGORY]->(root))
RETURN nodes(path) AS nodes
或者,您可以通过查找所有父项和子项然后将它们与您选择的编程语言组合到内存中来减少 return 所需的数据量:
MATCH (parent:Category)-[:SUB_CATEGORY]->(child:Category)
RETURN parent, child
您还可以创建一个 Neo4j 非托管扩展(基本上是 Neo4j 数据库的插件),它可以让您为 return 编写一些 Java 代码。
关于你的最后一个问题,已经回答的差不多了,但更直接的是:
MATCH (root:Category)
WHERE NOT(()-[:SUB_CATEGORY]->(root))
RETURN root
编辑:
我刚刚意识到你可能没有任意深入的尝试。如果它只有三个级别(而且如果它始终恰好是三个级别),您可以这样做:
MATCH (root:Category)-[:SUB_CATEGORY]->(parent:Category)-[:SUB_CATEGORY]->(child:Category)
WITH root, {category: parent, children: collect(child)} AS parent_with_children
RETURN {category: root, children: collect(parent_with_children)}