我们有树状组织的节点((:Object)-[:PARENT]->(:Object))一个对象可以使用多个项目({:Object)-[:USE]->(:Item))
我们想玩一个继承规则:如果父项使用一项,而子项没有具有相同属性的项,则=>子项将使用父项的项。
以下代码可以正常工作,但是在大型集上变得非常慢(我们有大约4k个对象,一个对象可能有2k个USE]
MATCH (p:Object)
WHERE p.rank = 1
WITH p
MATCH (p)-[:PARENT]->()-[:USE]->(used)
WHERE NOT exists((p)-[:USE]->(:Item {
property1:used.property1,
property2:used.property2,
property3:used.property3}))
MERGE (p)-[:USE]->(used);
您有更好的解决方案吗?
而不是制作Item节点的冗余副本(这很浪费,并且如果有任何“父” Item
发生更改,将需要进行额外的修复),而是可以根据需要查询继承的Item属性。
例如,获取每个p
节点的“已使用”属性(这些属性从父节点继承,然后由p
自己的属性覆盖):
MATCH (p:Object)
WHERE p.rank = 1
OPTIONAL MATCH (p)-[:PARENT]->()-[:USE]->(used1)
WITH p, REDUCE(s = {}, u IN COLLECT(used1) | apoc.map.merge(s, PROPERTIES(u))) AS x
OPTIONAL MATCH (p)-[:USE]->(used2)
RETURN p, REDUCE(t = x, v IN COLLECT(used2) | apoc.map.merge(t, PROPERTIES(v))) AS used