Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.
10-02-2019 07:32 AM
Hi!
I have read the documentation, and tried things, but seem unable to find the answer to the following (quite simple) questions.
I want to call shortestPath, have no property on nodes or links with a cost and want to restrict what nodes that should be traversed. How do I do that?
If I have a cost function, I think i could use the nodeQuery config to restrict to one label, but I have a couple of choices so I want to OR them..
Also since I have no cost function I dont really know how to pass the config parameters as it complains that it wants a string not a Map.
So I want a: call algo.shortestPath(start, end, {nodeQuery: "label1|label2"}).
Is this possible?
Thanks
10-02-2019 07:41 AM
What are you trying to achieve that you think requires "shortestPath" rather than a MATCH? The "shortestPath" requires a "cost" otherwise how can it calculate the shortest path? Do you mean fewest edges?
10-02-2019 02:33 PM
yeah.. fewest edges.. so having a constant cost for each edge.
10-02-2019 03:02 PM
You can use APOC path expander procs for this. By default it does a bfs expansion, and if you provide a limit
and supply the labels of nodes you want whitelisted in the labelFilter
you can get what you want:
MATCH (start:label1 {id:1234}), (end:label2 {id:5678})
CALL apoc.path.spanningTree(start, {endNodes:[end], limit:1, labelFilter:'label1|label2'}) YIELD path
RETURN path
Note that the labels in the labelFilter that you're whitelisting must include a label on your end node (it will not apply the filter to the start node by default, so the start node's label doesn't need to be in there.
That said, if the end node has a label that you don't want whitelisted for traversal, you can use an end label filter in the labelFilter
, which is the label prefixed with >
.
So if both the start and end node were :Node labeled, but you only wanted the middle nodes in the traversal to be :label1 or :label2 nodes, then you could use this:
MATCH (start:Node {id:1234}), (end:Node {id:5678})
CALL apoc.path.spanningTree(start, {endNodes:[end], limit:1, labelFilter:'label1|label2|>Node'}) YIELD path
RETURN path
As far as the "why spanningTree()?", it's a bit oddly named, but it uses NODE_GLOBAL
uniqueness during traversal, meaning a node will only ever be visited once, so there will ever only be a single path to each node (no cycles), so the collection of returned paths (if you don't have an end node, or any restriction on end nodes) takes the form of a spanning tree. The point is that with bfs expansion and NODE_GLOBAL uniqueness and the label filter (and supplying your end node) you get a shortest path using only the labels you want during the traversal.
10-03-2019 12:52 AM
Thanks! That works.. I do think that the graph algorithms should allow for just a constant weight though
10-03-2019 05:00 AM
I think you can do that too.
Under the documentation for the algo.shortestPath parameter weightProperty
:
The property name that contains weight. If null, treats the graph as unweighted. Must be numeric.
See if that works for you.
All the sessions of the conference are now available online