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.

all possible paths with directions and huge estimated rows !

mohsenshahbazi
Node Clone

Hi 

we have some data about some nodes that nodes connected to each other with relations we called them ( cable ) 

the number of nodes is : 349 and the number of cables is : 924 

we need to find possible path ( not shortest ) between two nodes and used this : 

MATCH p=(n:location)-[*]-(m:location)
WHERE n.lo_id = 70 AND m.lo_id = 486
AND ALL(x IN NODES(p) WHERE SINGLE(y IN NODES(p) WHERE y = x))
return p

but it's failed . i used to explain and saw in plan that in "VarLengthExpand(Into)@neo4j" about 

67,837,845,872,747,150,000 estimated rows !!! 

what's wrong with this query ? 

i'm newbie with neo4j . should i put index on fields or rewrite query ? 

would you please help me to make it work and find possible path with a good query between nodes ? 

Cypher version: CYPHER 4.4, planner: COST, runtime: INTERPRETED.

27 REPLIES 27

Cobra
Ninja
Ninja

Hello @mohsenshahbazi  ‌😊

What is the objective of the WHERE clause in your query?

Why don't you specify a relationship type?

Do you have multiple node types?

My first advice is to use apoc.path.expandConfig() procedure but I need more information on your graph model to help configuring it.

 

MATCH (n:location {lo_id: 70})
MATCH (m:location {lo_id: 486})
CALL apoc.path.expandConfig(n, {
    terminatorNodes: [m]
})
YIELD path
RETURN path;

 

You can specify uniqueness property in the procedure to make sure you don't have duplicates nodes in your path.

Regards,

Cobra

Hi Cobra , thanks for reply 

"What is the objective of the WHERE clause in your query?"  

i had may paths that repeated start or end node in path so searched in google and found this where in stackoverflow to prevent appearance of repeated nodes in path . 

"Why don't you specify a relationship type?" 

because i have 1 type of relationship just cable . 

[location:node1] --cable-->[joint:nodex1]--cable-->[location:node2]--cable-->[location:nodeN]--cable-->...[end]

"Do you have multiple node types?"

yes . 'location' and 'joint' . 

i tried to use allShortestPaths and apoc.allSimplePaths but this alogs just show paths contains location not joints .

This query should do what you want then:

MATCH (n:location {lo_id: 70})
MATCH (m:location {lo_id: 486})
CALL apoc.path.expandConfig(n, {
    relationshipFilter: "cable>",
    terminatorNodes: [m],
    uniqueness: "NODE_GLOBAL"
})
YIELD path
RETURN path;

thanks a lot . it's working most of things i want . but it's not  include joints node type in path and also it's returned just 1 path . i know between number of paths between this nodes is at least 6 . 

edited : wanted to thank you pointed to expandConfig . reading documentation is helping a lot to underestand what you wrote . 

Can you share a code to create the same database to try on my side? It will be easier for me to provide you the right solution:)

is there any way that i can export data like sqldump that you can import and check this out ? 

edit : i found a way to export as csv ( apoc.export.csv.all ) . is it ok ? 

i made it . how i can send it ? uploaded to dropbox

You can change the extension of the file to .txt to upload it here I guess.

Download

Here it is

Hi @mohsenshahbazi ,

Try with uniqueness set to : NODE_PATH

Oh, y’all wanted a twist, ey?

tried NODE_PATH but still doesn't include joint node type in path . just location node types . 

ameyasoft
Graph Maven

Try this: I created this scenario 

[location:node1] --cable-->[joint:nodex1]--cable-->[location:node2]--cable-->[location:node3]

match (a:Location {id:10})
CALL apoc.path.spanningTree(a, {}) YIELD path
return path
Result:
Screen Shot 2022-06-28 at 3.53.12 PM.png

 

thanks for reply . it's just a sample of schema . here is full db export that i used 

Download

Thank you @mohsenshahbazi 🙂

For me, 70 and 486 are neighbors so how do you find 6 paths between these nodes?

Regards,

Cobra

correct lo_id numbers is : start :69 | end : 489

This query returns 6 paths:

MATCH (n:location {lo_id: 69})
MATCH (m:location {lo_id: 489})
CALL apoc.path.expandConfig(n, {
    relationshipFilter: "cable>",
    terminatorNodes: [m],
    uniqueness: "NODE_PATH"
})
YIELD path
RETURN path;

Regards,

Cobra

Yes . it is . but there is no joint in path . 

here is a possible path that is not in result : 

lo_id : 69 -> jo_id : 275 -> lo_id : 70 -> lo_id : 489
or 
lo_id : 69 -> jo_id : 275 -> lo_id : 70 -> lo_id : 486 -> lo_id : 489 
this query just using location type nodes . not joints . and i said at least 6 paths in the way ( it was 1 path ) 

 

 

 

The node jo_id 275 has a relation with lo_id 70 but it's not in the right direction. Do you want do have directed path or you don't care about the direction?

I advice to use the direction or you will have the same original issue. What is the use case at the end?

i don't care about direction i just care about connection between nodes . i was used allShortestPath and it was bidirectional but i couldn't resolve all possible path from that . is it possible to make it happen in this way or should we make double cable relationship between nodes in both direction to prevent this problem ? 

i can make the cable from/to this joint but the database will have data redundancy and half of relationship data is just for prevent a simple problem . 

Nah,

You just need to remove the direction on the query

MATCH (n:location {lo_id: 69})
MATCH (m:location {lo_id: 489})
CALL apoc.path.expandConfig(n, {
    relationshipFilter: "cable",
    terminatorNodes: [m],
    uniqueness: "NODE_PATH"
})
YIELD path
RETURN path;

And read the docs too.

Oh, y’all wanted a twist, ey?

Thanks @bennu_neo 😊

@mohsenshahbaziI don't advise deleting the directions because the query will be MUCH LONGER. If you could explain your use case, we might find another solution based on a new data model to speed up the query.

It's important to understand the context, otherwise it's just a loopy lattice problem that has been a known problem on big data analysis. Your path exploration can easily explode.

Oh, y’all wanted a twist, ey?

i already tested it and crashed my server 😁

also tried to make a draw-back relationship of every cable that i make . but i was got worse so i step back . 
this is the story: 
we have multiple stations with two type of usage ( stations may be location or just a medium that connect a cable to another one because distance is too far  ) 
then we add this stations and those mediums ( called joint ) into neo4j as node(s) and connect  this nodes with relationships ( named :cable ) now operators need to resolve path between multiple stations and see some parameters based on this paths . i wrote this processor of path and will display map in visual way but i couldn't gather correct path from neo4j . its generated some path that does not include joints ( as mentioned before ) . 
i have a question . how allShortestPath resolving path so fast in bidirectional way but we can't ? if i use relationshipFilter: "cable" server got crashed !

is there any way to simulate allShortestPath with bidirectional path search that so fast ? 

Well, it's not about the bidirectionality itself, it's more about traversing condition that may allow you to avoid traversing your entire graph or getting into cycles. But this is just possible knowing the model. If you can detail yours a bit more, we may get a chance to optimize your use case.

Oh, y’all wanted a twist, ey?

what kind of additional data you need to know ? 

it may kind of twist .