繁体   English   中英

为什么通过CREATE或MERGE查询在Neo4j中创建多个节点

[英]Why multiple nodes are created in Neo4j by CREATE or MERGE query

我正在使用CypherNeo4j创建一些数据。 这是一个非常简单的产品模型,包含以下元素

  1. 产品(例如手机)
  2. 功能(例如快速充电)
  3. 相关产品(例如防篡改玻璃)
  4. 网点(例如本地商店,相关产品通过网点出售)

我写了一些查询来插入数据。 试图做的

  • 创建一个产品
  • 创建功能集
  • 将产品与功能[:HAS_FEATURES]关联
  • 创建网点x3
  • 创建相关产品1
  • 将产品链接到相关产品[:HAS_RP],并将相关产品链接到所有商店[:SOLD_THROUGH]
  • 创建相关产品2
  • 将其链接到上述产品和销售点

以下是实际查询

//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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM