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.

How to skip the intermediate nodes?

Based on the given input need to skip the specific nodes and continue with the nodes connected to them.

To simplify, say I have nodes like this:
A->B->C->D->E

I should query this graph in the following way:

if my input is B and C, I should skip B and C and just RETURN A->D->E

If my input is A, should return B->C->D->E

If my input is F, should return A->B->C->D->E

Typically these nodes are with the same Label but with different properties, assume the given input is a unique identifier that differentiates each of the nodes(maybe a name or id).
Have tried creating virtual nodes and virtual relationships, but couldn't get what I wanted.

Can anyone please help to have a query?

4 REPLIES 4

Hi @karthiksk

If you enter B and C, then A, D, and E are possible.
However, A->D->E will not appear as is because there is no relationship from A to D.
How about using Virtual Rels?

Thank you @koji for your reply.
If you enter B and C, then A, D, and E are possible.
--> How is this possible? Can you please give an idea or help with the query?

Have already looked at creating virtual relationships, the problem is I will not know the starting and ending nodes to form a virtual relationship easily since the ask will be to skip any intermediate nodes.
This kind of request may also come:
Input is B and D, should return A, C, E.

Hi @karthiksk

This is the data.

CREATE (:Some {name:"A"})-[:Next]->(:Some {name:"B"})-[:Next]->(:Some {name:"C"})-[:Next]->(:Some {name:"D"})-[:Next]->(:Some {name:"E"})

These are the connected nodes with A.

MATCH (a:Some {name:"A"})-[*]->(other)
RETURN a, other

Skip B and C, only A, D, and E will return.

WITH ["B","C"] AS skipnodes
MATCH (a:Some {name:"A"})-[*]->(other)
WHERE NOT other.name IN skipnodes
RETURN a, other

Hi @koji, I tried your query as you suggested, my requirement is to send the nodes in a pair like below.

A-B-C-D-E

if my input is B and D, I need to send (A, C), (C, E).

I tried to code this way, is this correct?

create(a:Label{name:"A", id:1})-[r1:CONNECTED]->(b:Label{name:"B",id:2})-[r2:CONNECTED]->(c:Label{name:"C",id:3})-[r3:CONNECTED]->(d:Label{name:"D", id:4})-[r:CONNECTED]->(e:Label{name:"E", id:5})
RETURN a,b,c,d,e

My input is to select A,D and E, I have a query like this:

optional match (n1:Label{name:"A"})
optional match (n2:Label{name:"D"})
optional match (n3:Label{name:"E"})
optional match p1 = (n)-[*1..5]-(n2)
OPTIONAL match p2 = (n2)-[*1..5]-(n3)


WITH collect(p1) as p1Paths,p1, collect(p2) as p2Paths, p2, n1, n2, n3
CALL apoc.case([
				size(p1Paths) > 0 AND size(p2Paths) > 0,
				"RETURN  [{source:n1.id, target:n2.id}] + [{source:n2.id, target:n3.id}] AS result",
				size(p1Paths) > 0,
				"RETURN {source:n1.id, target:n2.id} AS result",
				size(p2Paths) > 0,
				"RETURN {source:n2.id, target:n3.id} AS result"
				], 
				"RETURN null",{p1Paths:p1Paths,p2Paths:p2Paths,p2:p2,p1:p1,n1:n1,n2:n2,n3:n3})
YIELD value as result
UNWIND result.result as c
WITH DISTINCT c as list
RETURN {connectivity:collect(list)}

It will give desired results as below:
{
"connectivity": [
{
"source": 1,(A)
"target": 4 (D)
},
{
"source": 4, (D)
"target": 5 (E)
}
]
}

But if I have a connection like this:

create(a:Label{name:"A", id:1})-[r1:CONNECTED]->(b:Label{name:"B",id:2})-[r2:CONNECTED]->(c:Label{name:"C",id:3})-[r3:CONNECTED]->(d:Label{name:"D", id:4})-[r4:CONNECTED]->(d1:Label{name:"D", id:5})-[r5:CONNECTED]->(e:Label{name:"E", id:6})
RETURN a,b,c,d,d1,e

Now my query would return
{
"connectivity": [
{
"source": 1, (A)
"target": 4 (firstD)
},
{
"source": 4, (firstD)
"target": 6 (E)
},
{
"source": 1, (A)
"target": 5 (secondD)
},
{
"source": 5, second(D)
"target": 6 (E)
}
]
}

But I want a result like below:
A is connected to firstD, D is connected to secondD and second D is connected to E.
So, when my input is to select A,D and E, I would expect result also as (A,firstD), (firstD,secondD), secondD,E)

{
"connectivity": [
{
"source": 1, (A)
"target": 4 (first D)
},
{
"source": 4, (first D)
"target": 5 (second D)
},
{
"source": 5, (second D)
"target": 6 (E)
}
]
}

Can you please help to solve this in a better way?