首页 > 解决方案 > 在 Neo4j 中合并不存在的节点并返回源节点

问题描述

我在我的小应用程序中使用 neo4j 作为我的数据库。我的申请是关于管理候选人的简历(简历)。

这是我的图表:

简历管理

现在,我正在做的是添加一个项目,其中包含项目使用的技能列表。

这是我的 neo4j 查询:

MATCH (user: User)
WHERE (user.Id = "74994fd8-40bb-48e8-adf1-bc11eeb6c035")
WITH user
MERGE (project: Project {Id: '02d5ad72-036c-47e9-a366-d5ca4a3e66e2'})
ON CREATE
SET project = {
  Id: "02d5ad72-036c-47e9-a366-d5ca4a3e66e2",
  Name: "VINCI GTR",
  Description: "Description of VINCI GTR",
  StartedTime: 0.0
}
MERGE (user)-[:DID_PROJECT]->(project)
WITH project, user
MATCH (user)-[:HAS_SKILL]->(skill: Skill)
WHERE skill.Id IN []
MERGE (project)-[:USED_SKILL]->(skill)
RETURN project

在我的查询中,我使用:WHERE skill.Id IN []来确保我的技能列表为空,因为我想模拟没有可用技能的情况。

当我运行命令时,我无法接收新创建的项目,即使它已经在数据库中创建。我有这个结果:

Neo4j 结果

我怎样才能:

谢谢

标签: neo4jcypher

解决方案


匹配失败的MATCH子句会中止查询的其余部分(并且查询将不返回任何内容)。

以下代码段将永远不会匹配任何内容,因为它试图匹配user具有相关skill节点的节点,其Id值与不存在的值匹配(这没有意义):

MATCH (user)-[:HAS_SKILL]->(skill: Skill)
WHERE skill.Id IN []

要仅在没有技能的情况下创建USED_SKILL关系,请执行以下操作:user

MATCH (user: User)
WHERE user.Id = "74994fd8-40bb-48e8-adf1-bc11eeb6c035"
MERGE (project: Project {Id: '02d5ad72-036c-47e9-a366-d5ca4a3e66e2'})
ON CREATE
  SET project += {
    Name: "VINCI GTR",
    Description: "Description of VINCI GTR",
    StartedTime: 0.0
  }
MERGE (user)-[:DID_PROJECT]->(project)
WITH project, user
WHERE SIZE((user)-[:HAS_SKILL]->()) = 0
MERGE (project)-[:USED_SKILL]->(skill)
RETURN project

此查询对每个节点进行度数检查user以查找没有HAS_SKILL关系的节点(我们故意省略了:Skill模式中对面节点的标签,这是一种黑客手段,以使 Cypher 规划器生成更高效的操作)。此外,我们使用SET +=SET =不是替换所有节点属性,从而避免Id用相同的值覆盖该值。

顺便一提:

这种HAS_SKILL_CATEGORY关系似乎是多余的。如果用户的技能都可以通过HAS_SKILL关系达到,那么您已经可以通过以下方式获取该用户的类别:

MATCH (user: User)-[:HAS_SKILL]->()-[:BE_IN_SKILL_CATEGORY]->(c)
WHERE user.Id = "74994fd8-40bb-48e8-adf1-bc11eeb6c035"
RETURN c;

推荐阅读