NodeJS中如何在完成一个Cypher查询后执行另一个查询?
实现方法
你有两种可行的方式来完成这个需求,下面分别说明:
方式一:在同一个事务中执行两个查询
这种方式能保证两个操作的原子性——要么全部成功,要么全部回滚,适合需要数据一致性的场景。修改后的代码如下:
const myFunction = async function( req, res ){ const session = driver.session( { database:process.env.REACT_APP_NEO4J_DB } ); const txc = session.beginTransaction(); let result = null; try{ // 执行第一个合并节点的查询 result = await txc.run( `MATCH (n {id: $data1}), (m {id: $data2}) WITH head(collect([n,m])) as nodes CALL apoc.refactor.mergeNodes(nodes,{properties:"discard", mergeRels: true}) YIELD node RETURN node`, { 'data1': data1, 'data2': data2 } ) // 执行第二个更新关系属性的查询 await txc.run( `MATCH (n)-[r]->(m) SET r.sourceData = n.id, r.targetData = m.id` ) await txc.commit(); } catch(error){ await txc.rollback(); // 修正原代码笔误:catch参数为error,统一变量名 return res.status(400).json({ success: false, error: error, message: "操作失败" }) } finally{ await session.close(); return res.status(200).json({ success: true, data: result }) } }
注意点:
- 原代码
catch块里的err是笔误,已修正为error - 两个查询在同一个事务中执行,提交事务时才会将所有变更写入数据库
方式二:在第一个事务提交后执行第二个查询
如果两个操作不需要强原子性,可以在第一个事务提交后,单独执行第二个查询:
const myFunction = async function( req, res ){ const session = driver.session( { database:process.env.REACT_APP_NEO4J_DB } ); let result = null; let txc; try{ // 第一个事务:合并节点 txc = session.beginTransaction(); result = await txc.run( `MATCH (n {id: $data1}), (m {id: $data2}) WITH head(collect([n,m])) as nodes CALL apoc.refactor.mergeNodes(nodes,{properties:"discard", mergeRels: true}) YIELD node RETURN node`, { 'data1': data1, 'data2': data2 } ) await txc.commit(); // 执行第二个查询:更新关系属性 await session.run( `MATCH (n)-[r]->(m) SET r.sourceData = n.id, r.targetData = m.id` ) } catch(error){ // 第一个事务失败时回滚 if (txc) await txc.rollback(); return res.status(400).json({ success: false, error: error, message: "操作失败" }) } finally{ await session.close(); return res.status(200).json({ success: true, data: result }) } }
优化建议:
- 原第二个查询会匹配全库所有关系并更新,若只需处理和合并节点相关的关系,可缩小查询范围避免全库扫描,比如:
// 仅更新合并后节点关联的关系 MATCH (mergedNode)-[r]->(m), (n)-[r2]->(mergedNode) SET r.sourceData = mergedNode.id, r.targetData = m.id, r2.sourceData = n.id, r2.targetData = mergedNode.id
内容的提问来源于stack exchange,提问作者sazzad rahman
相关产品推荐
相关产品推荐

