cancel
Showing results for 
Search instead for 
Did you mean: 

Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.

Nesting apoc.path.subgraphAll inside apoc.when

mburbidg1
Node Clone

Our graph is a tree. I'm trying to build a query that given a node returns that node and optionally its ancestors and optionally its descendants. In other words I want to parameterize the query with parameters includeAncestors and includeDescendants.

This is my working query without parameters. i.e. It always returns both ancestors and descendants (and referenced nodes).

 

		MATCH (n:Entity {asset_id: $assetId, version: $version, id: $entityId})
		with n
		CALL apoc.path.subgraphAll(n, {
			WHERE $ancestors=True
			relationshipFilter : 'CHILD_OF>|<ATTACHED_TO',
			optional: true
		}) yield nodes, relationships
		with n, nodes as ascNodes, relationships as ascRel
		CALL apoc.path.subgraphAll(n, {
			WHERE $descendants=True
			relationshipFilter : '<CHILD_OF|<ATTACHED_TO',
			optional: true
		}) yield nodes, relationships
		with n, nodes as descNodes, relationships as descRel , ascNodes, ascRel
		CALL apoc.path.subgraphAll(n, {
			relationshipFilter : '<CHILD_OF|<ATTACHED_TO|REFERS_TO',
			optional: true
		}) yield nodes, relationships
		with n, nodes as refNodes, relationships as refRel , ascNodes, ascRel, descNodes, descRel
		CALL apoc.path.subgraphAll(refNodes, {
			relationshipFilter : 'CHILD_OF>|<ATTACHED_TO',
			optional: true
		}) yield nodes, relationships
		with n, nodes as refAscNodes, relationships as refAscRel, refNodes, refRel, ascNodes, ascRel, descNodes, descRel
		RETURN DISTINCT *

 

 Here's my first attempt to parameterize by an includeAncestors parameter. I modified the query as follows.

 

MATCH (n:Entity {asset_id: $assetId, version: $version, id: $entityId})
with n
CALL apoc.when(
    $includeAncestors,
    "CALL apoc.path.subgraphAll(n, {
        relationshipFilter : 'CHILD_OF>|<ATTACHED_TO',
        optional: true
    }) yield nodes, relationships",
    '',
    {n:n}
) yield nodes, relationships
CALL apoc.path.subgraphAll(n, {
    WHERE $ancestors=True
    relationshipFilter : 'CHILD_OF>|<ATTACHED_TO',
    optional: true
}) yield nodes, relationships
with n, nodes as ascNodes, relationships as ascRel
CALL apoc.path.subgraphAll(n, {
    WHERE $descendants=True
    relationshipFilter : '<CHILD_OF|<ATTACHED_TO',
    optional: true
}) yield nodes, relationships
with n, nodes as descNodes, relationships as descRel , ascNodes, ascRel
CALL apoc.path.subgraphAll(n, {
    relationshipFilter : '<CHILD_OF|<ATTACHED_TO|REFERS_TO',
    optional: true
}) yield nodes, relationships
with n, nodes as refNodes, relationships as refRel , ascNodes, ascRel, descNodes, descRel
CALL apoc.path.subgraphAll(refNodes, {
    relationshipFilter : 'CHILD_OF>|<ATTACHED_TO',
    optional: true
}) yield nodes, relationships
with n, nodes as refAscNodes, relationships as refAscRel, refNodes, refRel, ascNodes, ascRel, descNodes, descRel
RETURN DISTINCT *

 

But I get the following syntax error.
`

Unknown procedure output: `nodes` (line 11, column 11 (offset: 322))
"		) yield nodes, relationships"
           ^

Obviously I don't quite have it set up correctly. Can someone suggest a fix to my query?

Thanks,

Michael- 

2 REPLIES 2

mburbidg1
Node Clone

Here's the syntax I got to work regarding nested apoc calls.

CALL apoc.when(
    false,
    "CALL apoc.path.subgraphAll(n, {
        relationshipFilter : 'CHILD_OF>|<ATTACHED_TO',
        optional: true
    }) YIELD nodes, relationships
    RETURN nodes, relationships",
    "WITH n as nodes, [] as relationships
    RETURN nodes, relationships",
    {n:n}
) YIELD value
RETURN value

Duh, even simpler. I can do this without a nested apoc, by using the maxLevel parameter to the subgraphAll procedure as shown below.

 

MATCH (n:Entity {asset_id: "urn:aaid:sc:VA6:bbb6472c-34d5-4cf0-92e4-e2569c13b159", version: "#head", path: "artwork"})
with n
CALL apoc.path.subgraphAll(n, {
    relationshipFilter : 'CHILD_OF>|<ATTACHED_TO',
    optional: true,
    maxLevel: -1
}) YIELD nodes, relationships
RETURN nodes, relationships

If I want to include ancestors, in this case, the set maxLevel to -1. If I don't want to include ancestors, then set maxLevel to 0.