how to match 2 nodes by relationship in Neo4j? - neo4j

Given a list of (let say 4) MicroRNA and a list of relationships (pictar, rna22,…),
returns the list of target TargetGenes common to all MicroRNA in all relationships.
I am trying to do by this way but it does not work...
MATCH (n:microRNA)-[r]->(n:Target)
WHERE r.name='RNA22v2'
OR r.name='PicTar'
RETURN n
But it does not give me any results.

This may or may not be the actual problem, but instead of
MATCH (n:microRNA)-[r]->(n:Target)
WHERE r.name='RNA22v2'
OR r.name='PicTar'
RETURN n
shouldn't you have
MATCH (m:microRNA)-[r]->(t:Target)
WHERE r.name='RNA22v2'
OR r.name='PicTar'
RETURN m,t
Using the same variable n for two different nodes may confuse things.
Hope this helps,
Tom

Related

In neo4j how to return specific nodes or relationship with cypher?

You are given two arrays one for some labels and another for some relationships and you are asked to return the nodes and their relationships which are found only in the arrays you where given. I tried different approach to it but I couldn't get a better cipher to return the graph with respect to both arrays
MATCH (n)-[r]-(m) where n in ["username"] and r in ["knows"] return n,r
The code above, I know its completely wrong but it kinda shows the idea, share your thoughts 😁
This should work:
MATCH (n)-[r]-(m)
WHERE ANY(l IN labels(n) WHERE l IN ['username','label2'])
AND type(r) IN ['knows','relType2']
RETURN n,r,m

Neo4J, Match node with "OR"

Helo,
i want to match a graph where a node can be typeX or typeY
my first thought was:
match (:typeX|typeY)-[]-(z) return z
But this doesn´t work :(
Is there any way without typing the query twice?
Like this:
match (:typeX)-[]-(z), (:typeY)-[]-(z) return z
Can someone help me?
thank you in advance :)
One way is
MATCH (n) WHERE labels(n) IN ['typeX','typeY']
WITH n
MATCH (n)-[]-(z)
RETURN z
However, if "either typeX or typeY" are queried frequently and share some common purpose in your domain, you could add another common label to them like "commonXY" and query using that label instead.
Unfortunately there's not a good efficient way to do this without sacrificing performance. All other current answers are forced to scan all nodes and then filter on their labels, which isn't performant with large numbers of nodes (PROFILE the queries). All the efficient means I know of are more verbose.
You can perform a UNION of the two queries to return nodes one hop from all :typeX and :typeY nodes.
match (:typeX)--(z)
return z
union
match (:typeY)--(z)
return z
This query will work even if n has multiple labels:
MATCH (n)
WHERE ANY(lab IN labels(n) WHERE lab IN ['typeX', 'typeY'])
MATCH (n)--(z)
RETURN z
there is a n predicate n:Label
MATCH (n)--(z)
WHERE n:typeX OR n:typeY
RETURN z

How can I make the following Cypher query have the results that setting auto-complete control does?

I am doing the following Cypher query:
MATCH (a) WHERE a.itemId IN ['Q2', 'Q24', 'Q30', 'Q23', 'Q16', 'Q20'] RETURN a
I'd like it to return the same results as when I set the Auto-Complete switch. This question was asked and answered 1 but I don't understand the answer. Can this be performed in one query, and if so, what would the modified query be?
Yeah, you should be able to do it all in one query. To get the nodes in question along with their relationships you can do:
MATCH (a)
WHERE a.itemId IN ['Q2', 'Q24', 'Q30', 'Q23', 'Q16', 'Q20']
OPTIONAL MATCH (a)-[rel]-()
RETURN a, collect(rel)
That will return you, for each node, an array of the relationships.
Depending on your library that you're using for Neo4j, that may or may not return you something useful to give you the startnode/endnode. You could also do:
MATCH (a)
WHERE a.itemId IN ['Q2', 'Q24', 'Q30', 'Q23', 'Q16', 'Q20']
OPTIONAL MATCH (a)-[rel]-()
RETURN a, collect({rel: rel, start_node: startNode(rel), end_node: endNode(rel)})
That would give you an array for each node containing objects/maps of the data.
Got some separate clarification on the question about how to only return the relationships between the nodes that are matched. This should be possible like so:
MATCH (a)
WHERE a.itemId IN {itemIds}
OPTIONAL MATCH (a)-[rel]-(b)
WHERE b.itemId IN {itemIds}
RETURN a, collect(rel)
Again, you also might want to return the startNode/endNode of the relationships

Neo4j cypher - Counting immediate children of root nodes

I'm struggling with a problem despite having read a lot of documentation... I'm trying to find my graph root node (or nodes, they may be several top nodes) and counting their immediate children (all relations are typed :BELONGS_TO)
My graph looks like this (cf. attached screenshot). I have been trying the following query which works as long as the root node only has ONE incomming relationship, and it doesn not when it has more than one. (i'm not realy familiar with the cyhper language yet).
MATCH (n:Somelabel) WHERE NOT (()-[:BELONGS_TO]->(n:Somelabel)) RETURN n
Any help would be much appreciated ! (i haven't even tried to count the root nodes immediate children yet...which would be "2" according to my graph)
Correct query was given by cybersam
MATCH (n:Somelabel) WHERE NOT (n)-[:BELONGS_TO]->() RETURN n;
MATCH (n:Somelabel)<-[:BELONGS_TO]-(c:Somelabel)
WHERE NOT (n)-[:BELONGS_TO]->() RETURN n, count(c);
Based on your diagram, it looks like you are actually looking for "leaf" nodes. This query will search for all Somelabel nodes that have no outgoing relationships, and return each such node along with a count of the number of distinct nodes that have a relationship pointing to that node.
MATCH (n:Somelabel)
WHERE NOT (n)-[:BELONGS_TO]->()
OPTIONAL MATCH (m)-[:BELONGS_TO]->(n)
RETURN n, COUNT(DISTINCT m);
If you are actually looking for all "root" nodes, your original query would have worked.
As a sanity check, if you have a specific node that you believe is a "leaf" node (let's say it has an id value of 123), this query should return a single row with null values for r and m. If you get non-null results, then you actually have outgoing relationships.
MATCH (n {id:123})
OPTIONAL MATCH (n)-[r]->(m)
RETURN r, m

In neo4j is there a way to get path between more than 2 random nodes whose direction of relation is not known

I have a scenario where I have more than 2 random nodes.
I need to get all possible paths connecting all three nodes. I do not know the direction of relation and the relationship type.
Example : I have in the graph database with three nodes person->Purchase->Product.
I need to get the path connecting these three nodes. But I do not know the order in which I need to query, for example if I give the query as person-Product-Purchase, it will return no rows as the order is incorrect.
So in this case how should I frame the query?
In a nutshell I need to find the path between more than two nodes where the match clause may be mentioned in what ever order the user knows.
You could list all of the nodes in multiple bound identifiers in the start, and then your match would find the ones that match, in any order. And you could do this for N items, if needed. For example, here is a query for 3 items:
start a=node:node_auto_index('name:(person product purchase)'),
b=node:node_auto_index('name:(person product purchase)'),
c=node:node_auto_index('name:(person product purchase)')
match p=a-->b-->c
return p;
http://console.neo4j.org/r/tbwu2d
I actually just made a blog post about how start works, which might help:
http://wes.skeweredrook.com/cypher-it-all-starts-with-the-start/
Wouldn't be acceptable to make several queries ? In your case you'd automatically generate 6 queries with all the possible combinations (factorial on the number of variables)
A possible solution would be to first get three sets of nodes (s,m,e). These sets may be the same as in the question (or contain partially or completely different nodes). The sets are important, because starting, middle and end node are not fixed.
Here is the code for the Matrix example with added nodes.
match (s) where s.name in ["Oracle", "Neo", "Cypher"]
match (m) where m.name in ["Oracle", "Neo", "Cypher"] and s <> m
match (e) where e.name in ["Oracle", "Neo", "Cypher"] and s <> e and m <> e
match rel=(s)-[r1*1..]-(m)-[r2*1..]-(e)
return s, r1, m, r2, e, rel;
The additional where clause makes sure the same node is not used twice in one result row.
The relations are matched with one or more edges (*1..) or hops between the nodes s and m or m and e respectively and disregarding the directions.
Note that cypher 3 syntax is used here.

Resources