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

How to Recursively Create a Tree with Cypher (Neo4j)

提问人:Philippe Fanaro 提问时间:11/16/2023 最后编辑:Philippe Fanaro 更新时间:11/17/2023 访问量:41

问:

我正在尝试使用 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
         })

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

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

作为一种解决方法,我正在考虑首先创建所有 s,然后使用上面的查询将它们串回一起。它看起来像这样: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)
递归 neo4j 密码

评论


答:

1赞 Finbar Good 11/16/2023 #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})
}