Neo4j:如何在子查询中使用'order by'和'limit'?

4
我有一个数据模型,它是一棵树形结构,最大深度为3。例如:
          (a)       ... first level root node
        /  |  \
       /   |   \
     (b)  (b)  (b)  ... [0..n] number of second depth nodes
    / |         |
   /  |         |
 (c) (c)       (c)  ... [0..n] number of third depth nodes per (b) node

节点之间的关系为:(c)-[:in]->(b)-[:in]->(a) 给定一个根节点(a),我想创建一个查询,可以返回最近的10个(b)节点,以及每个(b)节点上最近的3个(c)节点。
我从获取最近的10个(b)节点的查询开始:
match (a) where id(a) = {root_id}
match (a)<-[:in]-(b) where b is not null
return b order by id(b) desc limit 10

这个代码可以按照预期获得最近的10个b节点。然而,我找不到一种方法来获取每个(b)里面最近的3个(c)节点。这是我的代码:

match (a) where id(a) = {root_id}
match (a)<-[:in]-(b) where b is not null
with b order by id(b) desc limit 10
optional match (b)<-[:in]-(c)
return b, c order by id(c) desc limit 3;

然而,limit 3适用于整个返回结果,而不仅仅是c子查询。
有没有一种方法可以将(c)子查询合并起来,使得limit 3对每个(b)节点只应用一次?
(我知道节点id不是最好的选择,因为它们易变。在这个例子中,我只是使用id()作为一种快速排序方式)
1个回答

5

您的查询几乎正确,对于每个b的最后3个c节点,您可以收集它们并仅返回集合中的3个节点:

match (a) where id(a) = {root_id}
match (a)<-[:in]-(b) where b is not null
with b order by id(b) desc limit 10
optional match (b)<-[:in]-(c)
with b, c order by id(c)
RETURN b, collect(c)[0..3] as c

在这里进行测试:http://console.neo4j.org/r/c16wak

注意:不需要使用where b is not null,使用MATCH时b永远不会为空。


collect()[0..n] 语法是我所缺失的。文档中没有展示这种组合,但我猜想这应该很明显,因为 collect() 返回一个集合。谢谢。 - dbcb
实际上文档中没有提到这个,也许我们应该加入这个技巧。不客气;-) - Christophe Willemsen

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