首页 > 解决方案 > 将模式有条件地部分合并到图中

问题描述

我正在尝试创建一种将人与城市-> 州-> 国家联系起来的关系,而无需重新创建城市/州/国家/地区节点和关系(如果它们已经存在)-所以我最终只会得到一个美国节点例如在我的图表中

我从一个人开始

CREATE (p:Person {name:'Omar', Id: 'a'})
RETURN p

然后我想apoc.do.case用 apoc 把它变成一个语句,或者把它变成一个合并语句

// first case where the city/state/country all exist
MATCH (locality:Locality{name:"San Diego"})-[:SITUATED_IN]->(adminArea:AdministrativeArea { name: 'California' })-[:SITUATED_IN]->(country:Country { name: 'USA' })
MERGE (p)-[:SITUATED_IN]->(locality)-[:SITUATED_IN]->(adminArea)-[:SITUATED_IN]->(country)
return p

// second case where only state/country exist
MATCH (adminArea:AdministrativeArea { name: 'California' })-[:SITUATED_IN]->(country:Country { name: 'USA' })
MERGE (p)-[:SITUATED_IN]->(locality:Locality{name:"San Diego"})-[:SITUATED_IN]->(adminArea)-[:SITUATED_IN]->(country)
return p

// third case where only country exists
MATCH (country:Country { name: 'USA' })
MERGE (p)-[:SITUATED_IN]->(locality:Locality{name:"San Diego"})-[:SITUATED_IN]->(adminArea:AdministrativeArea { name: 'California' })-[:SITUATED_IN]->(country)
return p

// last case where none of city/state/country exist, so I have to create all nodes + relations
MERGE (p)-[:SITUATED_IN]->(locality:Locality{name:"San Diego"})-[:SITUATED_IN]->(adminArea:AdministrativeArea { name: 'California' })-[:SITUATED_IN]->(country:Country { name: 'USA' })
return p

这里的关键是我只想得到一个(加利福尼亚)->(美国)。我不希望那些节点和关系被重复

标签: neo4jcypherneo4j-apoc

解决方案


  1. 您使用的查询MATCH永远不会指定Person您想要的。像这样的变量名p只存在于查询的生命周期中(有时甚至不会那么长)。Sop在您的MATCH查询中不受约束,并且可能导致您的MERGE子句创建空节点。您需要添加MATCH (p:Person {Id: 'a'})到这些查询的开头(假设所有人都有唯一的 Id 值)。
  2. 确保所有需要的位置都存在并正确连接不应该是每个查询的责任——这对于每个查询来说都过于复杂和开销。相反,您应该在需要它们之前分别创建适当的位置和跨位置关系。事实上,每个查询都应该负责创建一个位置来创建与其关联的所有关系。
  3. 如果模式中的每个事物都已经存在,则AMERGE不会创建指定的模式,因此为避免重复,MERGE 模式应该最多有 1 个可能不存在的事物。因此,一个模式最多应该有 1 个关系,如果它有一个关系,那么 2 个端节点应该已经被绑定(例如,通过子句)。MERGEMATCH

一旦Locality节点和区域间关系存在,您可以像这样添加一个人:

MATCH (locality:Locality {name: "San Diego"})
MERGE (p:Person {Id: 'a'}) // create person if needed, specifying a unique identifier
ON CREATE SET p.name = 'Omar'; // set other properties as needed
MERGE (p)-[:SITUATED_IN]->(locality) // create relationship if necessary

上述注意事项应有助于您设计用于创建Locality节点和区域间关系的代码。


推荐阅读