Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.
01-23-2022 07:34 PM
In my project, Neo4J stores staff nodes and relationships between staff.
People who have been to the same place within A period of time will have A relationship. For example, A and B have arrived at the same scene within A day, and A and B will have an association relationship.
I need to focus on any one person and find all the people within three degrees of path depth. My search statement is as follows:
MATCH p = (x:user)-[r:REL*1..3]->(y:user)
where x.user_id = '20121'
UNWIND NODES(p) AS n
WITH p,
SIZE(COLLECT(DISTINCT n)) AS testLength
WHERE testLength = LENGTH(p) + 1
RETURN p
When the site is small, there is no problem in searching in this way, and the path is obtained:
10*9*8
1000*999*988
, which is a disaster Solved! Go to Solution.
01-25-2022 07:34 AM
In this case you'll need to use apoc.path.spanningTree()
, which does YIELD path
instead of node.
The paths will automatically be shortest paths, since the procedure uses breadth-first expansion, and will only use the first path found to a node and no other.
01-24-2022 12:58 AM
I don't know if it's what you need,
but If you can use APOC procedures maybe you could write your query like this:
MATCH p = (x:user)-[r:REL*1..3]->(y:user)
where x.user_id = '20121'
with collect(NODES(p)) as nodes, collect(relationships(p)) as rels
return apoc.coll.toSet(apoc.coll.flatten(nodes)) as nodes, apoc.coll.toSet(apoc.coll.flatten(rels)) as rels
or with a map return:
return {nodes: apoc.coll.toSet(apoc.coll.flatten(nodes)), rels: apoc.coll.toSet(apoc.coll.flatten(rels))}
01-25-2022 12:22 AM
Thank you for your help. Maybe I didn't express it clearly in my question. Is there any way to query only the shortest path, for example, query only [P1 ->p2], [P1 ->p3]... [p1 - > p10] such a shortest path, exclude [p1 - > p3 - > p2], [p1 - > p4 - > p3 - > p2] such a path
01-24-2022 03:05 PM
If your use case is to find distinct people within 3 degrees (and you don't actually care about distinct paths the way Cypher does) then you can use apoc.path.subgraphNodes()
, a path expander procedure in APOC Procedures that is optimized for finding distinct nodes (and pruning any path found to a previously-encountered node).
MATCH (x:user)
WHERE x.user_id = '20121'
CALL apoc.path.subgraphNodes(x, {maxLevel:3, relationshipFilter:'REL>', labelFilter:'>user'}) YIELD node as y
RETURN y
This will only give distinct nodes back, it won't give back paths. If you want paths, then use apoc.path.spanningTree()
instead, but be aware that it will only give back a single path per reached nodes, not multiple paths.
01-25-2022 12:31 AM
Thanks for your help I need to find not only nodes, but also the shortest path between nodes. This is what I want: Nodes :[P2, P3, P4, P5, P6, P7, P8, P9, P10], rel: [p1 - > p2], [p1 - > p3], [p1 - > p4], [p1 - > p5], [p1 - > p6], [p1 - > p7], [p1 - > p8], [p1 - > p9], [p1 - > p10]
I do not know how to write such a statement, looking forward to your help
01-25-2022 07:34 AM
In this case you'll need to use apoc.path.spanningTree()
, which does YIELD path
instead of node.
The paths will automatically be shortest paths, since the procedure uses breadth-first expansion, and will only use the first path found to a node and no other.
01-25-2022 07:08 PM
thanks a lot! The apoc.path.spanningTree() function solved my problem. thanks again!
All the sessions of the conference are now available online