【发布时间】:2021-03-28 23:38:40
【问题描述】:
我有一系列已售菜单项 (SMI) 节点(即在商店出售的项目)。在 SMI 下方列出了基本菜单项 (BMI),它们代表组成 SMI 的组件。例如,对于快餐,SMI 可能是套餐,而 BMI 可能是可乐、薯条和三明治。 SMI 节点为蓝色,BMI 节点为绿色。红色节点代表地理位置并有自己的层次结构(商店 -[inherits_from]-> 地区 -[inherits_from]-> 市场)。
SMI/BMI 层图:
我要做的是指定在市场级别销售的 SMI,并让区域和商店继承 和/或修改这些关系。在上图中,我可以让 Store 1234 从其父美国市场继承 SMI 和关系。我还尝试模拟一个示例,其中美国市场销售 4 件商品,但特定区域 (NY) 仅销售 3 件商品,即纽约地区具有报价关系,但报价已停用(属性)。
这是 Cypher CREATE 语句:
CREATE (:Component {value: "Ketchup"})<-[:made_of]-(n1:BMI {value: "Hamburger",
version: "default"})-[:made_of]->(oz_Beef_Patty:Component {value: "4oz Beef Patty"})
<-[:made_of]-(n13:BMI {value: "Hamburger", version: "New York"})-[:can_add]->
(n5:Component {value: "Folded Egg"})<-[:made_of]-(:BMI {value: "Folded Egg"})<-
[:contains {geoId: "USM"}]-(n15:SMI {value: "Folded Egg"}), (n17:SMI {value:
"Hamburger"})-[:contains {geoId: 1234}]->(n23:BMI {value: "Hamburger", version:
"Store 1234"})<-[:contains {geoId: 1234}]-(Hamburger_Extra_Value_Meal:SMI {value:
"Hamburger Extra Value Meal"})-[:contains {geoId: "NYR"}]->(n13)-[:can_add]->
(American_Cheese:Component {value: "American Cheese"})<-[:can_add]-(n1)-[:can_add]->
(n5)<-[:can_add]-(n23)-[:made_of]->(Onions:Component {value: "Onions"}),
(Salt:Component {value: "Salt"})<-[:made_of]-(n1)-[:made_of]->(Onions)<-[:made_of]-
(n13)-[:made_of]->(Salt)<-[:made_of]-(n23)-[:made_of]->(Mustard:Component {value:
"Mustard"}), (Pickle:Component {value: "Pickle"})<-[:made_of]-(n1)-[:made_of]->
(Mustard)<-[:made_of]-(n13)-[:made_of]->(Pickle), (Roma_Tomato:Component {value:
"Roma Tomato - 2 Slices"})<-[:can_add]-(n1)-[:made_of]->(Regular_Bun:Component
{value: "Regular Bun"})<-[:made_of]-(n13)-[:can_add]->(Roma_Tomato)<-[:can_add]-
(n23)-[:can_add]->(American_Cheese), (New_York_Region:Geo {value: "New York Region",
level: "Region", id: "NYR"})-[:offers {status: "inactivated"}]->(n15)<-[:offers
{status: "activated"}]-(US_Market:Geo {value: "US Market", level: "Market", id:
"USM"})<-[:inherits_from]-(New_York_Region)<-[:inherits_from]-(:Geo {value: "Store
3456", level: "Store", id: 3456}), (n2:BMI {value: "M French Fry"})<-[:contains
{geoId: "USM"}]-(Hamburger_Extra_Value_Meal)<-[:offers {status: "activated"}]-
(US_Market)-[:offers {status: "activated"}]->(n17)-[:contains {geoId: "USM"}]->(n1),
(:Geo {value: "Store 1234", level: "Store", id: 1234})-[:inherits_from]->(:Geo
{value: "Chicago Region", level: "Region", id: "CHR"})-[:inherits_from]->
(US_Market)-[:offers {status: "activated"}]->(:SMI {value: "M French Fry"})-
[:contains {geoId: "USM"}]->(n2), (Hamburger_Extra_Value_Meal)-[:contains {geoId:
"USM"}]->(n1), (n17)-[:contains {geoId: "NYR"}]->(n13), (Regular_Bun)<-[:made_of]-
(n23)-[:made_of]->(oz_Beef_Patty)
当我执行以下查询时...
MATCH (geo:Geo)-[:inherits_from*0..]->(geos:Geo)
WHERE geo.value = "Store 1234"
WITH geos
OPTIONAL MATCH (geos)-[o:offers]->(smis)-[c:contains]->(bmis)
WHERE c.geoId in [(g1:Geo)-[:inherits_from*0..]->(gs:Geo) WHERE g1.value = "Store 1234" | gs.id]
return geos,smis,bmis
我得到了我期望的产品,即在美国市场级别指定的产品。相反,如果我指定 Store 3456,则节点 Folded Egg 将显示两个地理区域的关系。理想情况下,我希望该地区的关系在结果输出中“取消”美国市场与折叠蛋的关系。
结果:
有谁知道我是如何实现这种关系“分层”或“叠加”的行为?或者也许是另一种建模我的对象以更好地实现上述功能的方式?我不想在区域级别重复美国市场级别已经存在的关系。提前致谢!
在我上面的评论中,我不是试图在模型中创建关系,只是删除查询结果中已经存在的节点的关系。例如,我尝试了以下查询...
MATCH (geo:Geo)
WHERE geo.value = "Store 3456"
CALL {
WITH geo
OPTIONAL MATCH (geo:Geo)-[o1:offers]->(smis)
RETURN collect(smis) as totalSMIs, collect(geo) as totalGeos
}
CALL {
WITH geo, totalSMIs, totalGeos
OPTIONAL MATCH (geo)-[:inherits_from]->(geos1)-[:offers]->(regionSMIs)
RETURN apoc.coll.union(apoc.coll.removeAll(collect(regionSMIs), totalSMIs), totalSMIs) AS totalSMIs2,
apoc.coll.union(totalGeos, collect(geos1)) as totalGeos2
}
CALL {
WITH geo, totalSMIs2, totalGeos2
OPTIONAL MATCH (geo)-[:inherits_from]->(geos1)-[:inherits_from]->(geos2)-[:offers]->(marketSMIs)
RETURN apoc.coll.union(apoc.coll.removeAll(collect(marketSMIs), totalSMIs2), totalSMIs2) as totalSMIs3,
apoc.coll.union(totalGeos2, collect(geos2)) as totalGeos3
}
WITH totalSMIs3, totalGeos3
UNWIND totalGeos3 AS x
UNWIND totalSMIs3 AS y
MATCH (x)-[:inherits_from*0..]->(geos)-[o:offers]->(y)
WHERE o.status <> "inactivated"
RETURN DISTINCT totalSMIs3, totalGeos3
删除链接在不同层次结构级别的节点,我仍然得到所有错误的节点。我试图用上面做的是删除被覆盖的关系。例如,在数据中,美国市场销售折叠蛋([:OFFERS {status:activated}]),但纽约地区用它自己的关系([:OFFERS {status:inactivated}])覆盖了该选择。当我执行上面的代码时,我仍然看到两个 geos 和 Folded Egg 之间的两个关系。我只想要来自纽约地区的节点和关系,而不是来自美国市场 b/c 纽约地区有它自己的关系。
【问题讨论】: