How to extract a graph out of Neo4J and reconstruct it in the programming language - neo4j

Consider I have a bunch of connected nodes in Neo4J, forming a tree or a graph or whatever, and I want to have them in the programming language that I'm using (I'm using Java but that's not important).
I know I can have them all with a single cypher query like this:
MATCH (n0:Root)-[:Child*0..]->(nx:Node) WHERE ID(n0) = 1 RETURN nx;
But the problem I have here is that once returned to Java, I don't know which node is connected to which! How can I return the data so I can reconstruct the graph in my programming language?
I can see that the Neo4J web interface is doing that but I don't know how!?

In your query you are returning only :Node and not any relationship info or :Root nodes.
One example would be to return the ids of nodes and type of relationships between them
MATCH (s)-[r]->(t)
RETURN id(s) as source,id(r) as target,type(r) as relationship_type
You can modify this query depending on what you want to export.
The whole idea is to return nodes in pairs (source)->(destination). If you want to export only a specific subgraph that is connected to a specific starting node labeled :Root, you can return the graph like this:
MATCH (n0:Root:Node)-[:Child*0..]->(n1:Node)-[:Child]->(n2:Node)
RETURN n1, n2;

As an alternative, if you have access to APOC Procedures, you can take advantage of apoc.path.subgraphAll(), which gives you a list of all nodes in the subgraph, and all relationships between nodes in the subgraph.
MATCH (n0:Root)
CALL apoc.path.subgraphAll(n0,{relationshipFilter:'Child>'}) YIELD nodes, relationships
...

Related

How to get all connected nodes in neo4j

I want to get list of all connected nodes starting from node 0 as shown in the diagram
Based on your comment:
I want to get a list of all the connected nodes. For example in the
above case when I search for connected nodes for 0, it should return
nodes- 1,2,3
This query will do what you want:
MATCH ({id : 0})-[*]-(connected)
RETURN connected
The above query will return all nodes connected with a node with id=0 (I'm considering that the numbers inside the nodes are values of an id property) in any depth, both directions and considering any relationship type. Take a look in the section Relationships in depth of the docs.
While this will work fine for small graphs note that this is a very expensive operation. It will go through the entire graph starting from the start point ({id : 0}) considering any relationship type. This is really not a good idea for production environments.
If you wish to match the nodes that have a relationship to another node, you can use this:
MATCH (n) MATCH (n)-[r]-() RETURN n,r
It will return you all the nodes that have a relationship to another node or nodes, irrespective of the direction of the relationship.
If you wish to add a constraint you can do it this way:
MATCH (n:Label {id:"id"}) MATCH (n)-[r]-() RETURN n,r
For larger or more heavily interconnected graphs, APOC Procedures offers a more efficient means of traversal that returns all nodes in a subgraph.
As others have already mentioned, it's best to use labels on your nodes, and add either an index or a unique constraint on the label+property for fast lookup of your starting node.
Using a label of "Label", and a parameter of idParam, a query to get nodes of the subgraph with APOC would be:
MATCH (n:Label {id:$idParam})
CALL apoc.path.subgraphNodes(n, {minLevel:1}) YIELD node
RETURN node
Nodes will be distinct, and the starting node will not be returned with the rest.
EDIT
There's currently a restriction preventing usage of minLevel in subgraphNodes(), you can use either filter out the starting node yourself, or use apoc.path.expandConfig() using uniqueness:'NODE_GLOBAL' to get the same effect.

neo4j query to exclude nodes related to nodes with certain properties

I am trying to write a neo4j query where I only want to present nodes that are have no relation to nodes with a specific property. One way to think of it is where two separate graphs exist where one node has the property I want to exclude. I should get a result that only contains the graph of the set of nodes not connected to the node that has the property I want to exclude. This is what the graph looks like before my query
match (n) where not (n{property:'valueIWishToExclude'})--() return n
This is what the result of the query looks like
I only want to have the four connected nodes in my results. How can I set up a query that excludes the nodes that are not connected to the node with the property I wish to exclude?
In fact you need those nodes from which there is no path to the node that should be excluded. You can use the shortestPath function and ALL predicate:
match (ex) where n.property = 'valueIWishToExclude'
with collect(ex) as exn
match (n) where (not n.property = 'valueIWishToExclude') and
ALL(e in exn where not shortestPath( (n)-[*]-(e) ) is null)
return n
You are almost there, just add in the relationship in your query to only get the nodes that are related to each other
MATCH (n:label) -[:RELATED]->() where n.property<>'exclude'
RETURN n
That should return only the nodes connected to each other, as the other nodes do not have that relationship.
Let me know if that worked for you.
You may want to alter your wording a bit, what you're asking for in this question, and what you really want, are not the same thing.
In Neo4j (and most graph databases), the phrase "nodes that have no relation to..." means nodes that are not connected by a relationship to the node in question.
In that context, in your right graph (assuming the one node selected is the node marked as excluded), one node would fit the criteria and be returned as a possible result, the topmost node, since it doesn't have a relationship to the node you want to exclude; It is however two relationships removed from the excluded node.
You seem to be asking for something else, though. You seem to want nodes that are not in the same subgraph as the node to exclude. Or, alternately, nodes that have no path to the excluded node.
Make sure on future queries you're clear about what you're asking, or you'll get answers that have no relevance to what you really want.
One approach that will work is to first find all nodes within the subgraph of the excluded node, and then return all nodes that are not in those subgraph nodes.
You'll want to install APOC Procedures so you can make use of a fast means of obtaining nodes within the subgraph.
You'll also want to use labels in your graph, and maybe put an index on the property you're searching for as this will make your search fast. As it is now, your query must examine every node in your entire database to find nodes with the property in question, and that will become slower and slower as your graph grows.
Your query might look like this (using 'Label' as a stand-in for the node label):
MATCH (n:Label{propertyToExclude:'valueToExclude'})
CALL apoc.path.expandConfig(n, {bfs:true, uniqueness:"NODE_GLOBAL"}) YIELD path
WITH COLLECT(DISTINCT LAST(NODES(path))) as subgraph
MATCH (n)
WHERE NOT n in subgraph
RETURN n

Find some connection between two node in Neo4j movie database

How can I find some connection between the Actor node with id=1100 and the Actor node with id=65731 in Neo4j graph Movie database from the neo4j sample dataset? I have tried a lot but so far I know that id 11oo is Arnold Schwarzenegger and id 65731 is Sam Worthington.When I run Cypher using ACTS_In relationship its shows no movie together.
For finding name i have used this Cypher:
MATCH (a:Actor {id:"1100"}),(b:Actor {id:"65731"})
RETURN a.name, b.name
For finding relationship I have used this Cypher:
Match(a:Actor{name:"Arnold Schwarzenegger"})-[:ACTS_IN]->()<-[:ACTS_IN]-(b:Actor{name:"‌Sam Worthington"})
using index a:Actor(name)
using index b:Actor(name)
return count(*)
I am looking for any kind of connection. Not only the same movie.
In general, to find the paths between any 2 nodes, you can perform a variable-length relationship query.
For example:
MATCH path=(a:Actor{name:"Arnold Schwarzenegger"})-[*]-(b:Actor{name:"Sam Worthington"})
RETURN path;
Note, however, that unbounded variable-length relationship queries can take a very long time to complete (or may seem to never complete), even with relatively small DBs. The best practice is to put a reasonable upper bound on the depth of the query. For example, to search for path depths of at most 5:
MATCH path=(a:Actor{name:"Arnold Schwarzenegger"})-[*..5]-(b:Actor{name:"Sam Worthington"})
RETURN path;

Get full graph that node N is a part of in neo4j

I'm trying use Cypher to get the entire graph that exists if I start at a given node in neo4j. When I say entire graph I mean all nodes and relationships that are connected to at least one other node in the graph.
I've seen examples where people can get all nodes that might be connected to a given start node with a known relationship. Examples of this include this and this, but how could I do this if I do not know the relationships?
Ultimately I'd like every node and relationship where I start at one given node and sprawl out, listing the nodes that are linked by every relationship.
I've tried this:
START n=node(441007) MATHC (n)-[:*]->(d) RETURN d
but the syntax is incorrect. I'm unsure if you can submit a wildcard relationship. Additionaly I do not think this will give me what I am looking for.
Try this:
MATCH (n)-[r*]->(d)
WHERE ID(n) = 441007
RETURN r, d
This will fan out from n (if using an older version of Neo, you should revert to your START syntax) and return you the paths to each d Node that can be reached. It is relationship type agnostic through not defining the relationship label. If you didn't care about the path you could omit itwith:
MATCH (n)-[*]->(d)
WHERE ID(n) = 441007
RETURN d
Obviously on a large graph this will get expensive!
Edit
Meant to add the link to the cheat sheet, check out the section called Patterns.
Hej WildBill,
i have created a Company Graph for learning Neo4J, so i send the following Pattern against the Graph a got this result:
START a=node(9)
MATCH (a)<-[rel]-(d)
MATCH (d)-[sk]->(skill)
RETURN a, d, skill
Node 9 is my Company, which is part of the Graph.

Extract subgraph in neo4j

I have a large network stored in Neo4j. Based on a particular root node, I want to extract a subgraph around that node and store it somewhere else. So, what I need is the set of nodes and edges that match my filter criteria.
Afaik there is no out-of-the-box solution available. There is a graph matching component available, but it works only for perfect matches. The Neo4j API itself defines only graph traversal which I can use to define which nodes/edges should be visited:
Traverser exp = Traversal
.description()
.breadthFirst()
.evaluator(Evaluators.toDepth(2))
.traverse(root);
Now, I can add all nodes/edges to sets for all paths, but this is very inefficient. How would you do it? Thanks!
EDIT Would it make sense to add the last node and the last relationship of each traversal to the subgraph?
As for graph matching, that has been superseded by http://docs.neo4j.org/chunked/snapshot/cypher-query-lang.html which would fit nicely, and supports fuzzy matchin with optional relationships.
For subgraph representation, I would use the Cypher output to maybe construct new Cypher statements for recreating the graph, much like a SQL export, something like
start n=node:node_auto_index(name='Neo')
match n-[r:KNOWS*]-m
return "create ({name:'"+m.name+"'});"
http://console.neo4j.org/r/pqf1rp for an example
I solved it by constructing the induced subgraph based on all traversal endpoints.
Building the subgraph from the set of last nodes and edges of every traversal does not work, because edges that are not part of any shortest paths would not be included.
The code snippet looks like this:
Set<Node> nodes = new HashSet<Node>();
Set<Relationship> edges = new HashSet<Relationship>();
for (Node n : traverser.nodes())
{
nodes.add(n);
}
for (Node node : nodes)
{
for (Relationship rel : node.getRelationships())
{
if (nodes.contains(rel.getOtherNode(node)))
edges.add(rel);
}
}
Every edge is added twice. One time for the outgoing node and one time for the incoming node. Using a Set, I can ensure that it's in the collection only once.
It is possible to iterate over incoming/outgoing edges only, but it is unclear how loops (edge from a node to itself) are handled. To which category do they belong to? This snippet does not have this issue.
See dumping the database to cypher statements
dump START n=node({self}) MATCH p=(n)-[r:KNOWS*]->(m) RETURN n,r,m;
There's also an example for importing the subgraph of first database (db1) into a second (db2).

Resources