How to remove additional match from the query?

Hi guys!
I've made a graph (group tree)

create (root:Group:Limited:Root{id:1, limited:true, lim:200, amount:200})
create (root)-[:PARENT]->(c2:Group{id:2, limited:false, lim:-1, amount:200})
create (root)-[:PARENT]->(c3:Group{id:3, limited:false, lim:-1, amount:200})
create (root)-[:PARENT]->(c4:Group{id:4, limited:false, lim:-1, amount:200})
create (c4)-[:PARENT]->(c5:Group{id:5, limited:false, lim:-1, amount:200})
create (c4)-[:PARENT]->(c6:Group{id:6, limited:false, lim:-1, amount:200})
create (c5)-[:PARENT]->(c7:Group{id:7, limited:false, lim:-1, amount:200})
create (c7)-[:PARENT]->(c8:Group{id:8, limited:false, lim:-1, amount:200})
create (с7)-[:PARENT]->(c9:Group{id:9, limited:false, lim:-1, amount:200})
CREATE (c9)-[:PARENT]->(c10:Group{id:10, limited:false, lim:-1, amount:200})
CREATE (c9)-[:PARENT]->(c11:Group{id:11, limited:false, lim:-1, amount:200})

It looks like tihs in browser

I've made a query for recalculation node after update

MATCH (parentNode:Group{id:7})
SET parentNode:Limited, parentNode.limited = true, parentNode.amount = 10, parentNode.lim = 10
WITH parentNode
MATCH childPathNodeForUpdate=(parentNode)-[:PARENT*]->(:Group)
WHERE all(cn in nodes(childPathNodeForUpdate) where cn.limited = false or cn.id = parentNode.id)
with nodes(childPathNodeForUpdate) as nodesArray
Unwind nodesArray as nodesArrayConverted
with  nodesArrayConverted as nodesArrayConverted  where  nodesArrayConverted.id <>  7
WITH collect(nodesArrayConverted) as nsk
foreach (cnfu in nsk | SET cnfu.amount = 10)
WITH 1 as nothing
MATCH (nfs:Group{id:7})
WITH nfs as nodeForSearch
CALL apoc.path.expandConfig(nodeForSearch, {
    relationshipFilter: "<PARENT",
    labelFilter: "/Limited"
})
yield path 
with last(nodes(path)) as firstLimitedParentNode
MATCH pathForUpdate=(firstLimitedParentNode)-[:PARENT*]->(:Group)
WHERE all(n in nodes(pathForUpdate) where n.limited = false or n.id = firstLimitedParentNode.id) 
WITH nodes(pathForUpdate) as nodesFromReleation
UNWIND nodesFromReleation as nodesArray
WITH collect(DISTINCT nodesArray) as nodesForUpdate
FOREACH (nodeForUpdate in nodesForUpdate | set nodeForUpdate.amount = nodeForUpdate.amount - 10)

It works for me, but I have a couple of questions about the syntax
In first row I do

MATCH (parentNode:Group{id:7})

but when I want to get access in rows below, I need to do match again just for syntax needs
Can I avoid this?
And additional question
Can I use properties outside FOREACH statement inside foreach?
I've tried do that like

WITH node.amount as minusAmount
FOREACH (n in nodes | set n.amount = n.amount - minusAmount)

But it doesn't work.

Thanks for your help!

Hi @alexander_kaluz !

Glad to see you around.

Yes, I'll show you how.

Nope. They are node dependant and you neeed to iterate over a collection.

So this is my query version of your problem

WITH 10 as limVal
MATCH (parentNode:Group{id:7})
SET parentNode:Limited, 
parentNode.limited = true, 
parentNode.amount = limVal, 
parentNode.lim = limVal
WITH parentNode, limVal
call apoc.path.subgraphNodes(parentNode, {
    minLevel : 1,
    relationshipFilter: "PARENT>",
    labelFilter: "-Limited"
}) yield node
SET node.amount = limVal
WITH distinct parentNode as nodeForSearch , limVal
CALL apoc.path.expandConfig(nodeForSearch, {
    relationshipFilter: "<PARENT",
    labelFilter: "/Limited"
})
yield path 
with last(nodes(path)) as firstLimitedParentNode, limVal
call apoc.path.subgraphNodes(firstLimitedParentNode, {
    minLevel : 0,
    relationshipFilter: "PARENT>",
    labelFilter: "-Limited"
}) yield node
SET node.amount = node.amount - limVal

Bennu

1 Like

@Bennu thank you so much! You are my hero!

1 Like