Using gds.graph.create.cypher to create subgraph based on node properties and relationship types

Apologies for what is likely a basic question. Having trouble with my search for answers. I'll create a simple example to get to my question:

Suppose I am working with a graph G in the browser --- associated with Star Wars.
Some (but not all) of the nodes of G are labeled "Character." These Character nodes have a "Side" property which is either (Rebel, Empire, or Neither).
One of the relationship types between Characters is "AppearedOnScreenWith" and this relationship type has an associated property called "Time" which represents how many minutes they appear on screen together.
I would like to run some algorithms on a specific subgraph of this graph. I only want to consider the Character nodes whose Side is "Rebel" and only those relationships between these nodes where the "Time" property is at least 5 minutes.

I know that I need to use gds.graph.create.cypher to create this subgraph, but I can't find examples that show how to create subgraphs in this setting based on node and relationship properties. (I've seen how to select certain node labels, but not certain properties.)

I'm assuming this is fairly easy and I'm being dense. Would someone be so kind as to share code that would create such a (sub)graph? Or point me toward a helpful resource?

Thanks very much.

You would probably want to use a cypher projection to create this virtual graph.

Docs here: https://neo4j.com/docs/graph-data-science/current/management-ops/cypher-projection/

I only want to consider the Character nodes whose Side is "Rebel" and only those relationships between these nodes where the "Time" property is at least 5 minutes

An example might be something like this:

CALL gds.graph.create.cypher('rebelGraph',
  'MATCH (c:Character { side: "Rebel" }) RETURN id(c) as id',
  'MATCH (a:Character)-[r:AppearedOnScreenWith]->(b:Character) WHERE r.time > 5 AND a.side="Rebel" AND b.side="Rebel" RETURN id(a) as source, id(b) as target'
);

(I might have messed up the syntax a bit, play with it, but this is in essence how to do it)

So the constraints aren't too tough, just basic Cypher constraints. The tricky part to remember is that creating the graph expects standard output columns. I.e. for nodes you always want to return an 'id' field, and for relationships you always want to return a source and a target as per the docs.

Hi David. I really appreciate you taking the time to offer advice. Your suggestion seems to work very nicely.

Do you happen to know (or might anyone else know) an easy way to view the result of a cypher projection in graph form? I guess I could export the projection into a new database and view it there, but I wonder if there is an easier way.

@john.harris if you use gds.graph.list() it will return information about the number of nodes/relationships in your in-memory graph, the properties loaded, and the basic schema. You can use gds.util.nodeProperty to return data from your in memory graph (see the docs for an example). You cannot visualize the in memory graph using Bloom, or run Cypher queries against it unless you use graph export.

1 Like

Hello,
I would like to create a catalog projection from a more complex Cypher expression involving multiple nodes and relationships. Below is an example of the query to create the subgraph. Is it possible to use a query like this for creating a projection ?
Thanks,
Nick

match (folder:Folder {id: "d6fe4330-ba38-426b-a706-a942f7fcf8fd"})-[:CONTAINS]->(asset:Asset)
-[:TAGGED_BY]->(standard:Standard)<-[:PREREQ]-(prereq:Standard)
match (section:Section {sk:"7e2760e0-2375-c9ca-5690-24006b7aa645"})<-[:MEMBER_OF]-(learner:Learner)
match (learner)-[:KNOWS]->(standard)
match (learner)-[:KNOWS]->(prereq)
return learner, standard, prerequisite