[英]Why multiple nodes are created in Neo4j by CREATE or MERGE query
我正在使用Cypher
在Neo4j
創建一些數據。 這是一個非常簡單的產品模型,包含以下元素
我寫了一些查詢來插入數據。 它試圖做的是
以下是實際查詢
//Product
CREATE (p:Product {name: 'Cool Mobile YX Plus',
key: 'MOB0001',
version: 'X.1'
}),
//Features
(f:Features {hasQuickCharge: true,
isAvailable: true,
hasVolte: false
})
MERGE (p) -[:HAS_FEATURES]-> (f)
//Outlets (:Product level lookup)
CREATE (o1:Outlet {productType: 'New', seller: 'National_Shops', prId: 'MOB0001'})
CREATE (o2:Outlet {productType: 'New', seller: 'Local_Shops', prId: 'MOB0001'})
CREATE (o3:Outlet {productType: 'New', seller: 'Online_Shops', prId: 'MOB0001'})
//Related products
CREATE (rps1:RPS {rpId: 'TGS1108',
rpName: 'YX Plus Tampered Glass',
price: 180.99
})
WITH rps1
MATCH (ol1:Outlet {productType: 'New', prId: 'MOB0001'})
MATCH (pr1:Product {key: 'MOB0001'})
MERGE (pr1) -[:HAS_RP {typeName: 'Child'}]-> (rps1)
MERGE (rps1) -[:SOLD_THROUGH]-> (ol1)
CREATE (rps2:RPS {rpId: 'CVR0204',
rpName: 'YX Plus back cover',
price: 299.00
})
WITH rps2
MATCH (ol2:Outlet {productType: 'New', prId: 'MOB0001'})
MATCH (pr2:Product {key: 'MOB0001'})
MERGE (pr2) -[:HAS_RP {typeName: 'ChargeFor'}]-> (rps2)
MERGE (rps2) -[:SOLD_THROUGH]-> (ol2)
現在的問題是, 第二個相關產品被創建了3次 ,與第一個相關產品一樣,該產品僅被創建了一次。
誰能幫我了解我在做什么錯? 同樣,以更好的方式編寫查詢的任何幫助都將是很棒的。
問題位於此處:
MATCH (ol1:Outlet {productType: 'New', prId: 'MOB0001'})
您在符合MATCH標准的3個節點之前創建了:
CREATE (o1:Outlet {productType: 'New', seller: 'National_Shops', prId: 'MOB0001'}) CREATE (o2:Outlet {productType: 'New', seller: 'Local_Shops', prId: 'MOB0001'}) CREATE (o3:Outlet {productType: 'New', seller: 'Online_Shops', prId: 'MOB0001'})
因此, MATCH (ol1:Outlet {productType: 'New', prId: 'MOB0001'})
將返回3行,對於每一行,它將執行查詢的下一部分,這是該部分的3倍:
MATCH (pr2:Product {key: 'MOB0001'})
MERGE (pr2) -[:HAS_RP {typeName: 'ChargeFor'}]-> (rps2)
MERGE (rps2) -[:SOLD_THROUGH]-> (ol2)
只需為@Christophe和@InverseFalcon已回答/評論的內容寫一個擴展名。 如重置查詢基數中所述 ,此問題是由多次執行CREATE
引起的。
查詢每行執行一次。 因此,當MATCH
后面跟隨CREATE
,根據匹配結果,CREATE語句可能會執行多次並創建多個數據副本(除非存在唯一/節點鍵約束),該副本原本只打算創建一次。
MERGE
不會創建多個副本,因此可以幫助解決該問題,但是MERGE仍會執行多次。
這可以通過使用WITH DISTINCT
來“重置查詢基數”來處理。 下面顯示了解決該問題的更新查詢,該圖顯示了新結果。
//Related products
CREATE (rps1:RPS {rpId: 'TGS1108',
rpName: 'YX Plus Tampered Glass',
price: 180.99
})
WITH rps1
MATCH (ol1:Outlet {productType: 'New', prId: 'MOB0001'}) //3 match
MATCH (pr1:Product {key: 'MOB0001'})
MERGE (pr1) -[:HAS_RP {typeName: 'Child'}]-> (rps1)
MERGE (rps1) -[:SOLD_THROUGH]-> (ol1)
//next part of query will execute 3 times
//reset cardinality back to 1 with WITH DISTINCT
WITH DISTINCT 1 AS ResetCardinality
CREATE (rps2:RPS {rpId: 'CVR0204',
rpName: 'YX Plus back cover',
price: 299.00
}) //now CREATE & following executes only once
WITH rps2
MATCH (ol2:Outlet {productType: 'New', prId: 'MOB0001'})
MATCH (pr2:Product {key: 'MOB0001'})
MERGE (pr2) -[:HAS_RP {typeName: 'ChargeFor'}]-> (rps2)
MERGE (rps2) -[:SOLD_THROUGH]-> (ol2)
既然我是新手,那么如果有人可以展示如何通過更好的書面查詢來更好地處理整個情況,那將會有所幫助。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.