![精通Neo4j](https://wfqqreader-1252317822.image.myqcloud.com/cover/113/47216113/b_47216113.jpg)
3.3.8 MERGE语句
MERGE语句可以确保图数据库中存在某个特定的模式。如果该模式不存在,则创建它。
3.3.8.1 简介
MERGE或者匹配已存在的节点并绑定到它,或者创建新的节点然后绑定到它。它有点像MATCH和CREATE的组合。通过这种方式可以确保你指定的某个数据存在数据库中。例如,可以指定图中必须包含一个特定name的user节点。如果不存在特定name的user节点,那么就会创建一个。
当在整个模式上使用MERGE时,要么是整个模式匹配到,要么是整个模式被创建。MERGE不能部分地应用于模式,如果希望部分匹配,可以将模式拆分为多个MERGE语句。
MERGE图例如图3-11所示。
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P167_90523.jpg?sign=1738851495-9DRCJ6k5rsgtMzd0jH4NbgsV5481Oxuh-0-fc65856d3f39eb5c182b4de1f4c6c3a3)
图3-11 MERGE图例
3.3.8.2 MERGE节点
1.合并带标签的节点
下面的例子合并给定标签的节点。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P167_102680.jpg?sign=1738851495-4P2VWBtdZPhXelgizi5dfYSaBv1WyyY6-0-7cb965fb7ab10ad3b2492c30feefde14)
因为没有包含Critic标签的节点,所以在数据库创建了新节点。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P167_101750.jpg?sign=1738851495-y1u6u5uTc6m9V48IWeiI9kEKyTDOYm5f-0-a3ee1d31e61ce720adf0fa7485df0e80)
2.合并带多个属性的单个节点
合并有多个属性但并不是所有属性都匹配到已存在节点的单个节点。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P167_102681.jpg?sign=1738851495-2u245ErlceB7dzWYOZVeQxkUMAjsRU9u-0-3e04bb3f7f0857c98010454e62e6bad5)
在数据库创建了名为Charlie Sheen的新节点,因为没有匹配到所有属性都吻合的节点。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P167_101753.jpg?sign=1738851495-f37aW0SbOSKDY1kS8tkMHcHWnOn5f7WG-0-6c90453bbcb6a476717e3e1a5527d3fd)
3.合并同时指定标签和属性的节点
合并单个节点,要求它的标签和属性都能匹配到已存在的节点。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P168_102682.jpg?sign=1738851495-mGL27rzVg607tzG4LnwXcLUg0hbrCzor-0-64fc2e9bea1aa317dbc11fbf82e4cd68)
匹配到Michael Douglas节点,同时返回它的name和bornIn属性。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P168_101756.jpg?sign=1738851495-dyixRZo21OgUq2FuxPbAEvoCTKgPd31D-0-e715e384733c72135eadabcfcb8b32fa)
4.合并属性来自已存在节点的单个节点
当每个绑定节点的属性p来自一个节点集时,如果p存在重复,创建的时候只会创建一次。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P168_102683.jpg?sign=1738851495-6wJ4HtyHPqlcVLNmptUUijxnpCOyUpki-0-768baaa22aec51ca7a0e6068395e6037)
本例中创建了三个City节点,它们的name属性分别为New York、Ohio和New Jersey。
注意:尽管MATCH匹配的结果总有三个节点的bornIn属性值都为New York,但只创建了一个New York节点。因为第一次匹配的时候,New York未匹配到,因此创建了一个。然后,新创建的New York被第二个和第三个匹配到了。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P168_101758.jpg?sign=1738851495-a9wWmoHScMo2Dj6HOPUnBvY2WHlXdjjp-0-f77940b48149b1118c1914639ec045fe)
3.3.8.3 MERGE在CREATE和MATCH中的使用
1.MERGE与CREATE搭配
检查节点是否存在,如果不存在,则创建它并设置属性。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P169_102685.jpg?sign=1738851495-InQ55B06pnIL78jF4yBzadvjd1Mte62F-0-8da60f47306e5ef8c0183893c3d7c260)
本查询创建了keanu节点,并将created属性设置为创建时的时间戳。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P169_101761.jpg?sign=1738851495-DDyKmgCAbu9DwHYTl50GZqe9Sgkfsbix-0-a0be3b588461205531ba9806a7206f64)
2.MERGE与MATCH搭配
匹配节点,并在找到的节点上设置属性。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P169_102686.jpg?sign=1738851495-dnXQyJkOuSlYHMFZ6xCb2LgOnmojjiWj-0-76f997ac1e28265410d9772240001ddc)
本查询找到所有的Person节点,并设置found属性为true,然后返回它们。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P169_101764.jpg?sign=1738851495-olg5fDXX0Aoxmt9zY0aU2rwxwQ7F1lIg-0-7709162238de8414895f83a1fe8b797e)
3.MERGE与CREATE和MATCH同时使用
检查节点是否存在,如果不存在,则创建它并设置属性。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P169_102687.jpg?sign=1738851495-BUWCdtLWEQ3fF072tLwMw0wqs1msBEgF-0-d491a64f6d20b6760292ac9fcd2055f8)
本查询创建keanu节点并设置created属性值为创建时的时间戳。如果keanu已经存在,将为它设置一个新属性lastSeen。也就是说,当keanu不存在时,创建后的keanu节点将没有lastSeen属性。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P170_101767.jpg?sign=1738851495-mtWOHeL2edTdBLJo7vpbkKb5z3SQboHZ-0-68a8da589b867972dedb4f6e6c344df5)
4.利用MERGE和MATCH设置多属性
如果需要设置多个属性,将它们简单地以逗号分开即可。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P170_102689.jpg?sign=1738851495-w6hvEM0INtnZX9RuW9PFTHXbk4TWmJDw-0-fb9f78428fda56bab56410e0ead93963)
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P170_101770.jpg?sign=1738851495-N8np4qnnPDcy8XwKZVF2FNcYVluVEg2R-0-0827fdc9a5a84711cbaab8352c24c3f5)
3.3.8.4 MERGE关系
MERGE可用于匹配或者创建关系。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P170_102690.jpg?sign=1738851495-mOWAXuYenvrR9OyqyvnawjF54OOLSdgi-0-71984e1f89beacf2b18b9e5cec6f556a)
因为Charlie Sheen参演了Wall Street,所以找到已存的关系并返回。
注意:使用MERGE去匹配或者创建关系时,必须至少指定一个绑定的节点。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P171_101772.jpg?sign=1738851495-2txZjAmH3EPP8wRofTFjPFFF1UEkrrMz-0-c8744c31635fc6521519cc308185ba52)
1.合并多个关系
当MERGE应用于整个模式时,要么全部匹配上,要么全部新创建。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P171_102691.jpg?sign=1738851495-wt1LeZfSKvkdNybwWAG0GWd85NslkIce-0-6657634bf3d2d648c6dd0bbeee785bc0)
在本例中,Oliver Stone和Rob Reiner未一起工作过。当试图在其之间合并一个电影连接时,Neo4j不会使用任何已存在的电影,而是创建一个新的movie节点。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P171_101775.jpg?sign=1738851495-i8il4QtxHSdctkFLQlyHU1fLasjd6OkA-0-f268f0fd1a5590e217c89a003f74b348)
2.合并无方向关系
MERGE也可以用于合并无方向的关系。当创建关系时,它将选择一个任意的方向。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P171_102692.jpg?sign=1738851495-spZf4d4FXwv45s1waRoB5I7uFPv5UpQA-0-ca5fcece4356499a24bd4e5da0864a0d)
因为Charlie Sheen和Oliver Stone相互不认识,所以MERGE查询将在他们之间创建一个KNOWS关系。创建的关系的方向是任意的。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P171_101778.jpg?sign=1738851495-uie5iOkfcnhllwBm2iP0rqw94EjzvMCX-0-c4ee2182c8fba77d4b76ee43b5d19a68)
3.合并已存在两节点之间的关系
MERGE可用于连接前面的MATCH和MERGE语句,在两个绑定的节点m和n上创建一个关系。m节点是MATCH语句返回的,而n节点是前面的MERGE语句创建或者匹配到的。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P172_102693.jpg?sign=1738851495-RdQHYLvDTIW8t0DjGyMikEL6z39veQ25-0-05367a3850b31826cd8bb7363753ea1f)
这个例子来自3.3.8节。第二个MERGE在每个人和他的bornIn属性对应的城市之间创建了一个BORN_IN关系。Charlie Sheen、Rob Reiner和Oliver Stone与同一个城市节点(New York)都有一个BORIN_IN关系。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P172_101781.jpg?sign=1738851495-s1zjDN6axpWF9cUh3WexAMKxMGa1KHrf-0-8d07c0b16027e067b75e72022c0654c9)
4.合并一个已存在节点和一个合并的节点之间的关系
MERGE能够同时创建一个新节点n和一个已存在节点m与n之间的关系。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P172_102694.jpg?sign=1738851495-FqBV7UHjSmALCm1cnDfqrZBtZXUDJ0CO-0-50f7207c7c8708752a9edae4e2bb7715)
在本例中,MERGE未匹配到,这里没有标签为Chauffeur的节点和HAS_CHAUFFUR关系。MERGE创建了5个带有Chauffeur标签的节点,每个节点的包含一个name属性,属性的值来自每个匹配到的Person节点的chauffeurName属性的值。MERGE同时还在每个Person节点与新创建的Chauffeur节点之间创建了一个HAS_CHAUFFEUR关系。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P172_101784.jpg?sign=1738851495-agTgC5tkoaHrrt53MD4d9c4mrECAoA3p-0-f1e1d42eb60ab45a50c3d162c9f00bed)
3.3.8.5 用MERGE的唯一性约束
当使用的模式涉及唯一性约束时,Cypher可以通过MERGE来防止获取相冲突的结果。在这种情况下,至多有一个节点匹配该模式。例如,给定两个唯一性约束:Person(id)和:Person(ssn),如果存在两个不同的节点分别是id为12和ssn为437或者只有一个节点有其中一个属性,那么MERGE (n:Person {id: 12, ssn: 437})这样的查询将失败。
下面的例子分别在Person的name和role属性上创建一个唯一性约束。
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P173_102695.jpg?sign=1738851495-EMZgarBbefbuPUetrBw3357UIF15Dku1-0-8b4af4724361441f87df51703d4640e0)
如果节点未找到,则使用唯一性约束创建该节点。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P173_102696.jpg?sign=1738851495-UkyGM5OPK81OIYbG5vRTcF1ooVom51d9-0-2af3b6af3deb43bb6c087c30891369b7)
本查询创建了laurence节点。如果laurence已经存在,MERGE则仅匹配已经存在的节点。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P173_102698.jpg?sign=1738851495-aSyvhlklpA1vIZfS0dkWLB5U1NcgR1Mv-0-4c98437a5c65131c3e7fa62bc4b38a12)
使用唯一性约束匹配已存在的节点。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P173_102697.jpg?sign=1738851495-1CRjqPQ9dpCAf9vQhtIswey6BTxmTiOa-0-9b96b3ee7b7c75b92241989407beef2f)
oliver节点已经存在了,因此MERGE只是匹配它而不创建。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P173_101790.jpg?sign=1738851495-5VTRSh0lPvL2kVtZoXifCwh72yfq00qb-0-3ccc7862d3cad45fb3c36f2e678cec4d)
1.唯一性约束与部分匹配
当只有部分匹配时,使用唯一性约束合并将失败。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P174_102699.jpg?sign=1738851495-R1tbuS2ehEvHJ6xDqRzAqg05WCwwomLj-0-1da85cac5a8769f7c84c36e92c85b503)
这里有一个唯一匹配到的name为Michael Douglas的节点,但没有具有唯一的role属性为Gordon Gekko的节点,因此MERGE匹配失败。
错误消息:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P174_102699a.jpg?sign=1738851495-rLevFGtVrrl0Oy5BkNlQghrwyDBURDo6-0-8cf84c26ab258847079cbc8226e084da)
2.唯一性约束与匹配冲突
当有匹配的冲突结果时,使用MERGE唯一性约束将失败。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P174_102700.jpg?sign=1738851495-v5OCSsborrVh8M7eQpEO1qqVFgZdsGId-0-6f626c4b2f40a797dc36b5410d2f5861)
错误消息:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P174_101796.jpg?sign=1738851495-oBOAZNrGCcd8ujf5yMTQBSr5HYUXQs5P-0-b158db10b58af42604ad037485c3e562)
3.3.8.6 使用map参数
MERGE不支持像CREATE节点时那样使用map参数。要在MERGE中使用map参数,需要显式地使用希望用到的属性。如下例所示。
参数:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P174_102701.jpg?sign=1738851495-d85YK3qWwr8dahzHD49t7w2DzTfCa9jR-0-85e74298dd7ce2049331dfabfde3e153)
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P174_102702.jpg?sign=1738851495-YtItOvTzKjZVifJb9g2dzGD5mH92gxBt-0-51164cc8f5c546c588d189e081e931b1)
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P174_101799.jpg?sign=1738851495-rE92GyJaRuvKCW9NLg9camYJQwlGoMoJ-0-8585153a764e431ee443de23b6a42d6e)