如果可选匹配 returns null,则创建节点

Create nodes if optional match returns null

我将使用的所有节点都有与之关联的唯一约束。

我试过像这样创建新节点(我考虑过 MERGE,所以它不会创建已经存在的节点):

MERGE (n:url{url_addr:'test.com'})-[:FROM_DEVICE]->(o:device{mode:'iphone'})

并且该节点已经存在 return出现此错误:

Node(21) already exists with label `url` and property `url_addr` = 'test.com'

很明显,因为我事先没有匹配它们,所以我这样做是为了传递结果属性:

MATCH (n:url{url_addr:'test.com'}), (o:device{mode:'iphone'})
MERGE (n)-[:FROM_DEVICE]->(o)

但是如果这些记录中的任何一条都不存在,则不会创建新节点。

所以我考虑使用 OPTIONAL MATCH,因为它会将任何不存在的值替换为 null,但这意味着它也会用 null 值替换我传递的属性。

OPTIONAL MATCH (n:url{url_addr:'test.com'}) RETURN n
MERGE n-[:FROM_DEVICE]->(o:device{mode:'iphone'})

它 return 编辑了这个错误:

Failed to create relationship `  REL87(d65d30eb-65f5-4460-b166-15996622cf1b)`, node `n` is missing. If you prefer to simply ignore rows where a relationship node is missing, set 'cypher.lenient_create_relationship = true' in neo4j.conf

所以我考虑使用 CASE 语句来首先验证匹配是否 return null 然后创建节点来定义关系,但事情并不顺利:

OPTIONAL MATCH (n:url{url_addr:'test.com'})
WITH n as test
RETURN CASE
    WHEN test IS NULL THEN CREATE (:url{url_addr:'test.com'})
END

发生这种情况:

Invalid input '{': expected
  "!="
  "%"
  ")"
  "*"
  "+"
  ","
  "-"
  "."
  "/"
  ":"
  "<"
  "<="
  "<>"
  "="
  "=~"
  ">"
  ">="
  "AND"
  "CONTAINS"
  "ENDS"
  "IN"
  "IS"
  "OR"
  "STARTS"
  "XOR"
  "["
  "^" (line 4, column 51 (offset: 135))
"        WHEN CASE IS NULL THEN CREATE (a:cookie_id{url:'test.com'})"
                                                   ^

删除节点的属性没有帮助。

MERGE 总是匹配或创建整个模式。因此,您可能希望拆分 MERGE 子句,以便它匹配或创建每个节点和关系:

MERGE (n:url {url_addr:'test.com'}) // match or create url node
MERGE (o:device {mode:'iphone'})    // match or create device node
MERGE (n)-[:FROM_DEVICE]->(o)       // match or create relationship

您可能还想看看使用 APOC 过程执行条件密码: https://neo4j.com/labs/apoc/4.2/cypher-execution/conditionals/