Neo4j: retrieve all non-referenced nodes - neo4j

I have a very simple data model with source-[:link]->target. I'd like to find out all the nodes, which have no incoming links e.g. the "roots" of my data model. How do I do that in Cypher?

You can filter on null values
START target=node(*)
MATCH target<-[r?:link]-source
WHERE r is null
RETURN target
For details, refer Cypher where clause documentation
Alternatively, you can also do
START target=node(*)
WHERE not(target<-[:link]-source)
RETURN target
*Note: not tested

start n=node(*)
match n<-[?]-m
with n, count(m) as c
where c=0
return n

Related

How to find all nodes between two nodes in graph database?

I`m using Cypher query language and I need to find nodes between node A and E. (A->B->C->D->E)
Next query returns all nodes including A and E, but i need to exclude them, to have B, C, D nodes. How can I filter my query result?
MATCH p= (A:City{name: 'City1'})-[:LINKED*]->(E:City{name: "City5"}) return nodes(p)
There are a number of ways you might do this, but a simple option is to just index into the node list using:
return nodes(p)[1..-1]

Multiple Match queries in one query

I have the following records in my neo4j database
(:A)-[:B]->(:C)-[:D]->(:E)
(:C)-[:D]->(:E)
I want to get all the C Nodes and all the relations and related Nodes. If I do the query
Match (p:A)-[o:B]->(i:C)-[u:D]->(y:E)
Return p,o,i,u,y
I get the first to match if I do
Match (i:C)-[u:D]->(y:E)
Return i,u,y
I get the second to match.
But I want both of them in one query. How do I do that?
The easiest way is to UNION the queries, and pad unused variables with null (because all cyphers UNION'ed must have the same return columns
Match (p:A)-[o:B]->(i:C)-[u:D]->(y:E)
Return p,o,i,u,y
UNION
Match (i:C)-[u:D]->(y:E)
Return NULL as p, NULL as o,i,u,y
In your example though, the second match actually matches the last half of the first chain as well, so maybe you actually want something more direct like...
MATCH (c:C)
OPTIONAL MATCH (connected)
WHERE (c)-[*..20]-(connected)
RETURN c, COLLECT(connected) as connected
It looks like you're being a bit too specific in your query. If you just need, for all :C nodes, the connected nodes and relationships, then this should work:
MATCH (c:C)-[r]-(n)
RETURN c, r, n

Output all direct neighbours in a JSON object

Is it possible to write a query in Cypher to format the output of the following query into a JSON object?
MATCH (n:Artist{name:'Metallica'})-[r]->(m:Album)
RETURN {node: n, neighbours: { type(r): collect(m) }}
Of course, this is not a valid Cypher query. I'm trying to see if there's any way to write a query that generates the concept proposed here? One another problem (other than type(r):) is with m and it needs to be grouped by type(r).
As Gabor Szarnyas said, in the current implementation of the cypher it is impossible to do exactly as you wish. But you can do it using user defined procedure apoc.map.fromPairs from APOC library:
MATCH (n:Artist {name:'Metallica'})-[r]->(m:Album)
WITH n, type(r) AS relType, collect(m) AS albums
WITH n, collect([relType, albums]) as pairs
CALL apoc.map.fromPairs( pairs ) YIELD value as neighbours
RETURN { node: n, neighbours: neighbours }
You can construct a map using map literals. According to its documentation:
From Cypher, you can also construct maps. Through REST you will get JSON objects; in Java they will be java.util.Map<String,Object>.
However, you have to specify the keys in the map in advance - you cannot use variables/expressions (such the value of type(r)) as keys. The closest I could get to your requirements is the following:
MATCH (n:Artist {name:'Metallica'})-[r]->(m:Album)
WITH n, type(r) AS albumType, collect(m) AS albums
RETURN { node: n, works: collect({ type: albumType, albums: albums }) }
(The query is syntactically correct, but I did not test it on any data.)
See also this related question: Cypher query with literal map syntax & dynamic keys

Neo4j indices slow when querying across 2 labels

I've got a graph where each node has label either A or B, and an index on the id property for each label:
CREATE INDEX ON :A(id);
CREATE INDEX ON :B(id);
In this graph, I want to find the node(s) with id "42", but I don't know a-priori the label. To do this I am executing the following query:
MATCH (n {id:"42"}) WHERE (n:A OR n:B) RETURN n;
But this query takes 6 seconds to complete. However, doing either of:
MATCH (n:A {id:"42"}) RETURN n;
MATCH (n:B {id:"42"}) RETURN n;
Takes only ~10ms.
Am I not formulating my query correctly? What is the right way to formulate it so that it takes advantage of the installed indices?
Here is one way to use both indices. result will be a collection of matching nodes.
OPTIONAL MATCH (a:B {id:"42"})
OPTIONAL MATCH (b:A {id:"42"})
RETURN
(CASE WHEN a IS NULL THEN [] ELSE [a] END) +
(CASE WHEN b IS NULL THEN [] ELSE [b] END)
AS result;
You should use PROFILE to verify that the execution plan for your neo4j environment uses the NodeIndexSeek operation for both OPTIONAL MATCH clauses. If not, you can use the USING INDEX clause to give a hint to Cypher.
You should use UNION to make sure that both indexes are used. In your question you almost had the answer.
MATCH (n:A {id:"42"}) RETURN n
UNION
MATCH (n:B {id:"42"}) RETURN n
;
This will work. To check your query use profile or explain before your query statement to check if the indexes are used .
Indexes are formed and and used via a node label and property, and to use them you need to form your query the same way. That means queries w/out a label will scan all nodes with the results you got.

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