Merge neo4j cypher更新现有节点或创建新节点

Merge neo4j cypher更新现有节点或创建新节点,merge,neo4j,cypher,Merge,Neo4j,Cypher,我有一个大约有900万个节点和1200万个关系的图。对于图中的每个节点,每个节点都有一个子集的属性,这些属性通过标签形成节点的唯一标识。图形正在由各种数据源更新,这些数据源会增加图形中的现有节点,如果节点不存在,则会创建新节点。我不想在更新期间根据图中唯一的属性集创建重复项 例如,图中有人,他们的唯一性由他们的名字和姓氏决定。以下代码用于创建两个不同的人: 之后,我从其中一个数据源收到以下数据记录(每行一条): 更新图形后,我希望有以下节点: (:Person{first:"fred",last

我有一个大约有900万个节点和1200万个关系的图。对于图中的每个节点,每个节点都有一个子集的属性,这些属性通过标签形成节点的唯一标识。图形正在由各种数据源更新,这些数据源会增加图形中的现有节点,如果节点不存在,则会创建新节点。我不想在更新期间根据图中唯一的属性集创建重复项

例如,图中有人,他们的唯一性由他们的名字和姓氏决定。以下代码用于创建两个不同的人:

之后,我从其中一个数据源收到以下数据记录(每行一条):

更新图形后,我希望有以下节点:

(:Person{first:"fred",last:"jones",language:"welsh",height:"188,eyes:"brown"})
(:Person{first:"barry",last:"smith",language"english",height:187})
(:Person{first:"fred",last"lake",height:201})
我正在尝试制定一个
MERGE
查询,它可以进行这种更新。我提出了以下方法:

  • 从使用唯一性属性(
    first
    last
    来自示例)查找或创建初始节点的
    MERGE
    开始
  • 然后执行包含传入记录中定义的每个属性的
因此,对于上述三个示例记录:

MERGE (p:Person{first:"fred",last:"lake"}) SET p.height = 201;
MERGE (p:Person{first:"barry",last:"smith"}) SET p.language = "english";
MERGE (p:Person{first:"fred",last:"jones"}) SET p.language = "welsh", p.height = 188;
MERGE (p:Person{first:"fred",last:"jones"}) SET p.eyes = "brown";
MERGE (p:Person{first:"barry",last:"smith"});

我已经尝试过这个方法,它是有效的,但我很想知道这是否是确保基于一组属性的节点唯一性并允许添加(或不添加)附加信息的最佳方法(最有效…)随着时间的推移,会有更新吗?

这只是一种简单的方法:如果您运行
合并
并创建或更新它会怎么样

给定你的记录列表,把每条记录看作一张地图:

{ first: "fred", last: "lake", height: 201 }
{ first: "barry", last: "smith", language: "english" }
{ first: "fred", last: "jones", language: "welsh", height: 188 }
{ first: "fred", last: "jones", eyes: "brown" }
{ first: "barry", last: "smith" }
然后以参数化方式编写查询:

MERGE (p:Person{ first: { map }.name, last: { map }.last }
ON CREATE SET n = { map }
ON MATCH  SET n += { map }
查询说明:

  • 在创建时,它应该使用
    {map}
  • 如果匹配
我在的控制台中运行了一些查询,并在匹配时进行了
合并
,它似乎将现有属性更新为新值。 我运行的查询如下:

MATCH (peter { name: 'Peter' }) RETURN peter
MERGE (peter { name: 'Peter' }) ON MATCH SET peter += { hungry: TRUE , position: 'Entrepreneur' }
MATCH (peter { name: 'Peter' }) RETURN peter
// added two new properties here
MERGE (peter { name: 'Peter' }) ON MATCH SET peter += { hungry: FALSE , position: 'Entrepreneur' }
MATCH (peter { name: 'Peter' }) RETURN peter
// hungry is now false in here

我认为这是最好的方法。根据您使用的Neo4j界面,您可以编写一个查询来处理所有问题,而无需自定义SET命令,但我猜您只是简化了问题并涵盖了这一点。

您有属性列表吗,或者它们可以是任何东西?@MarcoCI感谢您的回答。属性集很可能是已知的,但可能会随时间而变化。你认为这些知识会如何影响实现(知道集合还是不知道集合),一个“弗雷德·琼斯”永远不应该说威尔士语。他应该叫Llwyr Culhwch或类似的名字。谢谢你的回复。实现将基于服务器。因此,电线上的交通将非常重要。Cypher似乎可以在一次呼叫中促进详细的操作。我应该更仔细地看看其他RESTful API吗?(也就是说,为了提高性能)您看过基于REST的密码接口了吗?如果没有,它允许您在查询中使用参数,这是非常强大的。我不认为合并是可行的。谢谢你的后续建议:非常感谢。在我的第一篇博文之后,我阅读了更多关于带有地图功能的
合并
,我认为这看起来是一个很好的解决方案。你在匹配中缺少了一个结束括号:)这很好,谢谢!但是我认为n='和n+='中的n应该是p?
MERGE (p:Person{ first: { map }.name, last: { map }.last }
ON CREATE SET n = { map }
ON MATCH  SET n += { map }
MATCH (peter { name: 'Peter' }) RETURN peter
MERGE (peter { name: 'Peter' }) ON MATCH SET peter += { hungry: TRUE , position: 'Entrepreneur' }
MATCH (peter { name: 'Peter' }) RETURN peter
// added two new properties here
MERGE (peter { name: 'Peter' }) ON MATCH SET peter += { hungry: FALSE , position: 'Entrepreneur' }
MATCH (peter { name: 'Peter' }) RETURN peter
// hungry is now false in here