我们正在使用层次结构树结构,其中父项具有零个或多个子项,并且子项具有一个或零个父项。当我们查询给定父级的直接子级列表时,查询以随机顺序返回子级。我们需要孩子按照我们在创建或更新孩子时定义的顺序返回。
我添加了孩子之间的关系 - [:兄弟姐妹] - >所以' top'兄弟姐妹只有一个传入:兄弟姐妹关系,以及'底部'兄弟姐妹只有外向的关系。
鉴于此,是否有Cypher查询以兄弟顺序返回孩子?
我有一个返回每个子节点及其兄弟节点的查询,但现在我必须编写一些代码以正确的顺序返回列表。
另一种方法可能是为每个子节点添加排序编号。如果其中一个孩子改变了秩序,则需要为所有孩子更新。这种方法对于图数据库概念来说似乎有些陌生。
如果以前遇到过这个问题,是否有一个标准算法以编程方式解决它?
UPDATE1
根据Bruno的要求示例数据
(parent1)
(child1)-[:ChildOf]->(parent1)
(child2)-[:ChildOf]->(parent1) (child2)-[:Sibling]->(child1)
(child3)-[:ChildOf]->(parent1) (child3)-[:Sibling]->(child2)
是否有一个cypher查询以按顺序返回child1,child2,child3?
如果没有,则可以以编程方式完成排序
使用属性而非关系
(parent1)
(child1)-[:ChildOf]->(parent1) (child1:{order:1})
(child2)-[:ChildOf]->(parent1) (child2:{order:2})
(child3)-[:ChildOf]->(parent1) (child3:{order:3})
`match (c)-[:ChildOf]->(parent1) return c ordered by c:order`
我不希望有一个密码查询可以更新孩子的顺序。
UPDATE2
我现在已经到达以下查询,该查询以正确的顺序返回子项
`match (firstChild)-[:FirstChildOf]->(parent) match (sibling)-[:Sibling*]->(firstChild) return firstChild,sibling`
此查询取决于添加 - [:FirstChildOf] - >(父)关系。
如果我没有听到其他声音,我会将其设置为答案。
我是否假设没有用于将节点插入有序列表的密码查询?
答案 0 :(得分:1)
创建图表模型时,您应该专注于要用数据模型回答的问题。 如果你想得到一个父母的孩子,请按照"创建或更新"属性然后你应该存储它,因为一般的关系不代表订单。 由于图数据库使用属性,因此图数据库概念并不陌生。决定并不总是容易的任务 将某事物存放为关系或财产。这一切都与正确的建模有关。 如果你有' [:NEXT_SIBLING]'的概念或类似的,当你必须删除一个节点时,后面会很痛苦。所以当这个状态不变时我应该使用它。例如,在一个时间树中,日子在彼此之后并且它不会改变。
通常,如果应该使用创建顺序,我应该使用这样的时间戳:
create (n:Node {created:timestamp()});
然后您可以使用时间戳进行订购。
match (p:Parent)-[:HAS_CHILDREN]->(n:Child) where p.name='xy' return n order by n.created;
您也可以将时间戳用于关系。 类似的问题在这里: Modeling an ordered tree with neo4j
答案 1 :(得分:0)
以下是我用于处理Neo4J中有序节点列表的一些提示。
将关系方向反转为(child1)<-[:HasChild]-(parent1)
。 (主要是对下一个项目的逻辑强化,因为“父母有子女列表”)
将属性index
添加到HasChild。这将允许您为兄弟订单执行WITH child, hasChild.index as sid ORDER BY sid ASC
。 (这就是我如何维护子列表上的任意顺序信息)这是关系,因为它假定一个节点可以是多个有序列表的一部分。
您可以使用SIZE(shortestpath((root)-[*]->(child1)) as depth
然后从根目录按深度排序。
由于这是针对任意顺序的,因此必须更新所有索引以更新顺序(对于基本插入,您可以执行WITH COLLECT(child) as children, FILTER(c IN COLLECT(child) WHERE c.index >=3) as subset FOREACH (c IN subset| SET c.index+=1)
之类的操作,否则您只需将它们全部重写为任意改变顺序。
如果您实际上并不关心订单,只要它是一致的,您可以使用WITH child, ID(child) as sid ORDER BY sid ASC
。这基本上是“逐个节点年龄”
另一个选择是使用元关系。所以:HasChild
将充当节点列表,然后像:NextMember
这样的东西会告诉你这个节点的下一个项目是什么。这更灵活,但在我看来更难以使用(你需要为没有下一个的情况,为了获得正确的顺序,你必须在节点上做'跟踪',如果你想要的话不起作用稍后将此节点添加到另一个有序列表,等等。
当然,如果订单不是任意的(基于名称或年龄等),那么只需对非任意逻辑进行排序就好了。
答案 2 :(得分:0)
以正确顺序返回子项的查询是
match (firstChild)-[:FirstChildOf]->(parent) match (sibling)-[:Sibling*]->(firstChild) return firstChild,sibling