如何使用 Cypher (Neo4j) 递归创建树

问题描述 投票:0回答:1

我正在尝试使用 Cypher 在 Neo4j 上复制 SGF 游戏树。这棵树是这样的形状:

type GameTree = {
  id: number;
  data: { [key: string]: string[] };
  parentId: number | null;
  children: GameTree[];
};

这是我正在尝试解决的创建查询:

UNWIND $moves AS move

MATCH (parent)

WHERE ((parent:GameNode) OR (parent:MoveNode))
  AND parent.game_id = $gameId
  AND parent.id = move.parentId

CREATE   (parent)
        -[:NEXT_MOVE]
       ->(:MoveNode{
           game_id: $gameId,
           id:      move.id
         })

最初,树的根是

GameNode
,我单独创建它,因为它包含有趣的元数据。无论如何,这不会像这样工作,因为在
UNWIND
MATCH
子句时,只存在一个父级,其余的将/应该递归创建。

有没有办法在 Cypher 中进行这种递归创建?也许有一些我似乎找不到的递归关键字(这似乎是一个常见的问题......)?也许某处有有用的 APOC 程序?

作为解决方法,我正在考虑首先创建所有

MoveNode
,然后使用上面的查询将它们重新串在一起。它看起来像这样:

// 1. Create All The Move Nodes

UNWIND $moveNodes AS move

CREATE (:MoveNode{
         game_id: move.game_id,
         id:      move.id
       })

// 2. Tie them to their Parents

WITH move

MATCH (parent{
        game_id: move.game_id,
        id:      move.parentId
      }),
      (m:MoveNode{
        game_id: move.game_id,
        id:      move.id
      })

WHERE parent:GameNode
   OR parent:MoveNode
  
CREATE (parent)-[:NEXT_MOVE]->(m)
recursion graph neo4j tree cypher
1个回答
1
投票

如果每个查询执行都是针对按游戏顺序排列的单个移动链,并且父级

GameNode
已经存在,那么您可以使用以下命令:

UNWIND $moveNodes AS move
CALL {
    WITH move
    MATCH (parent:GameNode|MoveNode {game_id: $gameId, id: move.parentId})
    CREATE (parent)-[:NEXT_MOVE]->(m:MoveNode {game_id: $gameId, id: move.id})
}
© www.soinside.com 2019 - 2024. All rights reserved.