Reputation: 5617
Suppose I have a collection of 5 nodes in Neo4j, such that each node in the collection is connected to at least one other node in the collection. I want to extract the subgraph formed by the collection of nodes and their interactions from Neo4j. Currently, I'm using a really primitive method that involves attempting to find a match from each node in the system to every other node:
MATCH p=(n)-[]->(m)
WHERE id(n) IN [3,4,5,6,7] AND id(m) IN [3,4,5,6,7]
RETURN relationships(p);
However, this query is both redundant and inefficient; it must go through every permutation of nodes in the collection (e.g. it will match node #3 and #4, and ALSO #4 and #3). Is there any more efficient way of getting the subgraph formed by these nodes using Cypher ONLY (no Java)?
Here's an example of what I mean by "subgraph":
I want Cypher to return all the relationships marked in green. Please note that the nodes in the collection don't have to be isolated from the rest of the graph; they can still have relationships with other nodes in the graph, but I want Cypher to return only the relationships in green.
Upvotes: 3
Views: 6942
Reputation: 1227
I have developed a python library/CLI cypher-subgraph that rewrites and generates Cypher queries for supporting subgraphs.
The tool mimics the subgraph feature using the addition property for the nodes and edges. For each node and edge which is inside the "x" subgraph, the property "__subgraph_x" will be set true.
Currently, it has three commands "add-to", "rewrite-for", and "delete".
First, you can set all the nodes and edges you want to be a member of a subgraph, then you can execute everything you want in the created subgraph.
The "add-to" command rewrites a query that the returned results become the subgraph members.
MATCH (v) RETURN v => MATCH (v) WITH v SET v.__subgraph_sg = true
The "rewrite-for" command rewrites a query that only will be executed in the subgraph:
MATCH (v) RETURN v => MATCH (v { __subgraph_sg: true }) RETURN v
The "delete" command deletes subgraph related properties:
MATCH (v) OPTIONAL MATCH (v)-[e]-() REMOVE v.__subgraph_sg REMOVE e.__subgraph_sg
There is no known limitation on the reading queries. All the commands work well with Cypher nodes, edges, and paths.
Upvotes: 0
Reputation: 41676
I want to extend on Richards answer, you can also restrict it to nodes whose id's are in separate groups.
MATCH (n) WHERE id(n) IN [3,4,5,6,7]
MATCH p=(n)-->(m)
WHERE id(n) < id(m) AND id(m) IN [3,4,5,6,7]
RETURN relationships(p);
results in
Upvotes: 3
Reputation: 124
This modification of your query helps with the redundancy of arrays.
WITH [3,4,5,6,7] AS arr
MATCH p=(n)-[]->(m)
WHERE id(n) IN arr AND id(m) IN arr
RETURN relationships(p);
You can use labels of nodes or types of relationships for differentiation (eventual subgraphs) and efficient querying but it depends on your case.
Upvotes: 0