Skip to content

Instantly share code, notes, and snippets.

@jexp
Last active December 11, 2021 13:42
Show Gist options
  • Save jexp/a4c1dc0e04fff11a952892db08810f65 to your computer and use it in GitHub Desktop.
Save jexp/a4c1dc0e04fff11a952892db08810f65 to your computer and use it in GitHub Desktop.
Sorted Path Expand Question

Sorted Path Expansion by Node Property

Yesterday we got a question on Discord

Maxe — gestern um 19:40 Uhr

Hi folks,

I am searching for some way to expand a graph from one source node like with Apoc.path.expand. But I want to filter on each depth depending on properties.

For example, I want to expand a graph on each depth further with only the top 5 page rank nodes. Does someone have suggestions?

michael.hunger — heute um 03:43 Uhr

in cypher you an express conditions on the relationships or nodes of a path or oder paths by sum of their weights.

MATCH path = (a:Node {id:$id})-[:REL*..5]->(end)
RETURN path, apoc.coll.sum([r in relationships(path) | r.weight]) as weigth

you could invert the weight and use dijkstra?

you can also add a gh issue for apoc.path.expand to support filtering / costs or write your own proc. feel free to add a gh issue

Maxe — heute um 10:59 Uhr

Thank you for your response

I think this approach want work for me.

I want to expand my subgraph iteratively.

For example:

  • Depth 1: Top 5 Nodes with the highest PageRank

  • Depth 2: Expand from each Node of Depth 1 respectively the top 5 Nodes with the highest PageRank …

With your approach I would get in a global scope.

Do you have any further suggestions, actually I am using a query with the collect() and unwind() trick, but it doesn’t really satisfy my problem?

michael.hunger — heute um 14:33 Uhr

it doesn’t do it recursively.

So either you have to spell out each level in the cypher query, e.g. with subqueries, or use a procedure to use the TraversalAPI for full control.

Here is an example for 3 levels:

MATCH (a:Node) WITH a ORDER BY a.pagerank DESC LIMIT 5

CALL { WITH a
    MATCH (a)-[:NEXT]->(b) WITH b ORDER BY b.pagerank DESC LIMIT 5
    CALL { WITH b
        MATCH (b)-[:NEXT]->(c) WITH c ORDER BY c.pagerank DESC LIMIT 5
        RETURN c
    }
    RETURN b,c
}
RETURN a,b,c

The other option you could try is to get all paths and then ORDER the result by the PR of the node on posX and limit to 5^levels

MATCH (a:Node)-[:NEXT*3]->(c) // or (a:Node)-[:NEXT]->(b)-[:NEXT]->(c)
RETURN a, nodes(path)[1] as b, c
ORDER BY a.pagerank DESC, b.pagerank DESC, c.pagerank DESC
LIMIT 125 // 5^3
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment