Finding isolated/orphaned nodes in neo4j - neo4j

How can I find the nodes that have 0 edges? For example:
The item at the top, which is (d:Department {name: "A42"}), has zero edges. How can I just get those items with that property?

This does it
MATCH (n)
WHERE NOT (n)—()
RETURN n

The answer from Graphileon is correct, but in Neo4j 4.3+ there is a warning that this syntax will become deprecated. You can use the following instead:
MATCH (n)
WHERE NOT EXISTS ((n)--())
RETURN n

Here is a variation:
show each node label, where one or more nodes is orphaned (has no relationships with any other node)
include the count of those nodes as well
MATCH (x)
WHERE NOT EXISTS ((x)--())
RETURN distinct(labels(x)), count(*)
ORDER BY count(*) desc
This works as of Neo4j 4.4 (specifically, 4.4.5).

Related

neo4j query to match nodes based on the number of properties

I have a node with 8 properties and another node with only property under a common label. How can i match / query / display the nodes which has only property.
In other words, how can i match nodes which doesn't have more than 1 property.
You may want something like:
MATCH (n)
WHERE size(keys(n)) = 1
RETURN n
However note that this is a graph-wide query, and likely to be expensive. Confining the query to a label may help a little.
As Michael Hunger mentioned
MATCH (n) WHERE NOT EXISTS(n.foo) RETURN n
Duplicate of the question : Find neo4j nodes where property is not set

Create association between nodes if one doesnt exist using cypher

Say there are 2 labels P and M. M has nodes with names M1,M2,M3..M10. I need to associate 50 nodes of P with each Node of M. Also no node of label P should have 2 association with node of M.
This is the cypher query I could come up with, but doesn't seem to work.
MATCH (u:P), (r:M{Name:'M1'}),(s:M)
where not (s)-[:OWNS]->(u)
with u limit 50
CREATE (r)-[:OWNS]->(u);
This way I would run for all 10 nodes of M. Any help in correcting the query is appreciated.
You can utilize apoc.periodic.* library for batching. More info in documentation
call apoc.periodic.commit("
MATCH (u:P), (r:M{Name:'M1'}),(s:M) where not (s)-[:OWNS]->(u)
with u,r limit {limit}
CREATE (r)-[:OWNS]->(u)
RETURN count(*)
",{limit:10000})
If there will always be just one (r)-[:OWNS]->(u) relationship, I would change my first match to include
call apoc.periodic.commit("
MATCH (u:P), (r:M{Name:'M1'}),(s:M) where not (s)-[:OWNS]->(u) and not (r)-[:OWNS]->(u)
with u,r limit {limit}
CREATE (r)-[:OWNS]->(u)
RETURN count(*)
",{limit:10000})
So there is no way the procedure will fall into a loop
This query should be a fast and easy-to-understand. It is fast because it avoids Cartesian products:
MATCH (u:P)
WHERE not (:M)-[:OWNS]->(u)
WITH u LIMIT 50
MATCH (r:M {Name:'M1'})
CREATE (r)-[:OWNS]->(u);
It first matches 50 unowned P nodes. It then finds the M node that is supposed to be the "owner", and creates an OWNS relationship between it and each of the 50 P nodes.
To make this query even faster, you can first create an index on :M(Name) so that the owning M node can be found quickly (without scanning all M nodes):
CREATE INDEX ON :M(Name);
This worked for me.
MATCH (u:P), (r:M{Name:'M1'}),(s:M)
where not (s)-[:OWNS]->(u)
with u,r limit 50
CREATE (r)-[:OWNS]->(u);
Thanks for Thomas for mentioning limit on u and r.
I think one way to connect all 10 nodes :M in one query
MATCH (m:M)
WITH collect(m) as nodes
UNWIND nodes as node
MATCH (p:P) where not ()-[:OWNS]->(p)
WITH node,p limit 50
CREATE (node)-[:OWNS]->(p)
Although I am not really sure if we need to collect and unwind, could just simplify it to:
MATCH (m:M)
MATCH (p:P) where not ()-[:OWNS]->(p)
WITH m,p limit 50
CREATE (node)-[:OWNS]->(p)

How to find nodes with more than one relationship between each other with cypher in neo4j?

It is easy to identify nodes with a certain number of incoming or outgoing relationships, but I want to identify connection redundancies so I want to get a set of all nodes with more than one relationship towards each other.
Pseudo code which unfortunately does not return any results:
MATCH (n1)-[r]-(n2)
with distinct n1,r,n2, count(r) as sstcount
where sstcount > 1
RETURN n1,r,n2
I think I found a solution, the queries need to be correctly linked. Any "nicer solutions" highly appreciated.
MATCH (n1)-[r]-(n2)
WITH distinct n1,n2, count(r) as sstcount
MATCH (n1)-[r]-(n2)
where sstcount>1
return n1,r,n2
Try this one instead:
MATCH (n1)-[r]-(n2)
WHERE id(n1) < id(n2) // so we avoid matching to the same nodes in swapped order
WITH n1,n2, count(r) as sstcount
WHERE sstcount > 1
RETURN n1, n2

neo4j how to return all node labels with Cypher?

I can't find how to return a node labels with Cypher.
Anybody knows the syntax for this operation?
To get all distinct node labels:
MATCH (n) RETURN distinct labels(n)
To get the node count for each label:
MATCH (n) RETURN distinct labels(n), count(*)
There is a function labels(node) that can return all labels for a node.
Neo4j 3.0 has introduced the procedure db.labels() witch return all available labels in the database. Use:
call db.labels();
If you want all the individual labels (not the combinations) you can always expand on the answers:
MATCH (n)
WITH DISTINCT labels(n) AS labels
UNWIND labels AS label
RETURN DISTINCT label
ORDER BY label
START n=node(*) RETURN labels(n)
If you're using the Java API, you can quickly get an iterator of all the Labels in the database like so:
GraphDatabaseService db = (new GraphDatabaseFactory()).newEmbeddedDatabase(pathToDatabase);
ResourceIterable<Label> labs = GlobalGraphOperations.at(db).getAllLabels();
If you want to get the labels of a specify node, then use labels(node); If you only want to get all node labels in neo4j, then use this function instead: call db.labels;, never ever use this query: MATCH n RETURN DISTINCT LABELS(n). It will do a full table scan, which is very very slow..

Show all Nodes and Relationships in Data Browser Tab

How can I show all nodes and relationships in Data Browser tab?
What are sample index queries that I can type in in search field?
You may also want to try a cypher query such as:
START n=node(*) RETURN n;
It's very obvious, and it will return all the existing nodes in the database.
EDIT : the following displays the nodes and the relationships :
START n=node(*) MATCH (n)-[r]->(m) RETURN n,r,m;
More simple way is
MATCH (n) RETURN (n)
MATCH (n) OPTIONAL MATCH (n)-[r]-() RETURN n, r;
You can show everything with simple MATCH (n) RETURN n, as offical documentation suggests.
START n=node(*) RETURN n from Neo4j 2.0 is deprecated:
The START clause should only be used when accessing legacy indexes
(see Chapter 34, Legacy Indexing). In all other cases, use MATCH
instead (see Section 10.1, “Match”).
There is a little help icon beside the search field, if you hoover over it it shows the syntax.
If a property of your nodes and relationships is indexed you can search for all of them like this.
node:index:indexname:fieldname:*
rels:index:indexname:fieldname:*
I found that this worked, retrieving all nodes including orphans, and all relationships:
MATCH (n) MATCH ()-[r]->() RETURN n, r
Other good way for get ALL nodes (and nodes without relationship) :
MATCH (n) RETURN n UNION START n = rel(*) return n;

Resources