首页 > 解决方案 > 在创建关系时返回不匹配的节点 Neo4j Cypher

问题描述

我写了一个脚本来在neo4j中批量创建一堆关系。这是密码:

:param batch => [{startId: 'abc123', endId: 'abc321'}, {startId: 'abc456', endId: 'abc654']
UNWIND $batch as row
MATCH (from {id: row.startId}
MATCH (to {id: row.endId}
CREATE (from)-[rel:HAS]->(to)
RETURN rel

可能有一些 startId/endId 条目与任何节点都不匹配并且被静默忽略的问题。有没有办法返回不匹配任何节点的行列表并为匹配的节点创建关系?

一旦 id 找不到 startId/endId,我就尝试 OPTIONAL MATCH 快速失败,但是查询执行速度非常慢。

标签: neo4jcypher

解决方案


首先,您应该始终尝试为用于启动 a 的节点指定一个标签MATCH(除非该MATCH模式使用任何已绑定的节点)。否则,必须扫描数据库中的每个节点。此外,您应该考虑使用索引来加速您MATCH的 s (但同样,您需要指定标签)。

这是一个使用 APOC 过程apoc.do.when在适当时创建新关系的查询。它返回每个row和相应的新关系(或者NULL如果没有找到任何一个节点):

UNWIND $batch as row
OPTIONAL MATCH (from:Foo {id: row.startId})
OPTIONAL MATCH (to:Foo {id: row.endId})
CALL apoc.do.when(
  from IS NOT NULL AND to IS NOT NULL,
  'CREATE (from)-[rel:HAS]->(to) RETURN rel',
  'RETURN NULL AS rel',
  {from: from, to: to}) YIELD value
RETURN row, value.rel AS rel

推荐阅读