Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.
11-13-2020 05:00 AM
I would like to run some graph data science algorithms on a sub spanning tree of nodes and relations of a larger graph. To get the spanning tree, I use the APOC library.
MATCH (e:Entity)
WHERE e.property in ["foo", "bar"] # some property condition
CALL apoc.path.spanningTree(e, minLevel: 0, maxLevel: 3})
YIELD path
WITH collect(path) as paths
CALL apoc.graph.fromPaths(paths, "tree", null)
YIELD graph
RETURN *;
I'm now at a loss of how to get that subgraph into a graph data science graph though. I don't think the native projection can capture the complex substructure of a sub spanning tree from specific starting nodes.
The only way I can currently see is to use the cypher projection. I would need to unravel the node and relationship ids and add match for them, but that approach seems very inelegant.
The easiest way would probably be if I could directly pass node and relationship ids to gds.graph.create
, but that doesn't seem to be a possibility. Maybe I am missing something very obvious, but any and all suggestions would be appreciated.
11-13-2020 12:53 PM
I tinkered with this a bit, best I can tell the gds routines only operate on the main db store, I couldn't get them to recognize virtual relationships/nodes (or graph). It is what I expected, but gave it a try anyway. At the moment, I can see two ways to do this,
CALL gds.graph.create.cypher(
'my-cypher-graph',
'match (e:Gene {name:"SNCA"})
CALL apoc.path.spanningTree(e, {minLevel: 0, maxLevel: 3, limit: 25}) YIELD path
unwind nodes(path) as n return id(n) as id',
'match (e:Gene {name:"SNCA"})
CALL apoc.path.spanningTree(e, {minLevel: 0, maxLevel: 3, limit: 25}) YIELD path
unwind relationships(path) as r
RETURN id(startNode(r)) AS source, id(endNode(r)) AS target, type(r) AS type'
)
11-13-2020 01:25 PM
I hadn't thought of adding labels. That might be a good option. Thanks for the help though!
I'll also try asking in the GDS github repo to see if the devs have any other ideas. If anything comes up I'll post it here as well.
05-19-2021 10:55 AM
I have just been looking into a similar question, and using parameters you can pass in the node and relationship ids (GDSL docs - projection parameters)
So, a query using the base example from apoc.graph.fromPaths docs would be the following:
MATCH path = (:Person)-[:ACTED_IN]->(:Movie)
WITH collect(path) AS paths
CALL apoc.graph.fromPaths(paths,'test', {})
YIELD graph AS g
WITH [node in g.nodes | ID(node)] AS nodeIds,
[rel in g.relationships | [ID(startNode(rel)),ID(endNode(rel))]] AS relIds
CALL gds.graph.create.cypher(
'test-param-input',
'UNWIND $nodes AS id RETURN id',
'UNWIND $relationships AS rel RETURN rel[0] as source, rel[1] as target',
{
parameters: { nodes: nodeIds, relationships: relIds }
}
) YIELD graphName, nodeCount, relationshipCount
return graphName, nodeCount, relationshipCount
All the sessions of the conference are now available online