How to find what relations exists between 2 nodes neo4j? - neo4j

Lets say i have these nodes with these relations (A,B) are nodes and Rs are Relation Names:
A-R1->B
A-R2->B
A-R3->B
Now i do not actually know if one or any R has relation between these 2 nodes. how can i specify if any relation exists between these 2 nodes regardless of knowing what relation is it?
Also if there are any relation exists between these two nodes is it possible to know what relation is it?

how can i specify if any relation exists between these 2 nodes
regardless of knowing what relation is it?
I believe that a simple MATCH will be sufficient. The below query returns all relationships between a node named "A" and a node named "B", if exists.
MATCH ({name : "A"})-[r]->({name : "B"})
RETURN r
Also if there are any relation exists between these two nodes is it
possible to know what relation is it?
The type() function returns a string representation of the relationship type. Then the below query will return the string representing the type of each relationship between A and B.
MATCH ({name : "A"})-[r]->({name : "B"})
RETURN type(r) as type

Related

fetch path based upon relationship propertty in NEO4j

I want to find all those nodes that are connected to specific node based upon certain relationship label. This is what I have got so far,
Match (n:UMLSConcepts{ConceptID: 'C3254924'})-[:NDFRT {RelationLabel : "RO_may_be_treated_by"}]-> (m:UMLSConcepts) RETURN (n), (m)
where (n) is a specific node and (m) are all other nodes that are connected with this node. Problem with above statement is that it is dependent upon a specific relation type in this case(NDFRT), but I want all relation type that contains certain relationship properties in this case("RO_may_be_treated_by") because there could be path/edge in other relation type as well.
If I I fully understood your question, you can simply omit the relationship type in your Cypher query, this way:
Match (n:UMLSConcepts{ConceptID: 'C3254924'})-[{RelationLabel : "RO_may_be_treated_by"}]-> (m:UMLSConcepts)
RETURN (n), (m)

Neo4j: hierarchy finding cypher query

I am trying to find the hierarchy - both upward and downward for the following domain model. As being new to neo4j I am having some hurdle to get the right hierarchy with the cypher query.
Any assistance or sample would be a great help to me...
(:Person{id=1})-[HAS_CHILD]->(:Person{id=2})-[HAS_CHILD]->(:Person{id=3})-[HAS_CHILD]->(:Person{id=4})-[HAS_CHILD]->(:Person{id=5})
....like that to a very deep level & one person can have multiple children.
I am trying to build some query to find
A Person and all his children hierarchy
A person and his parent hierarchy
Relation ship between two person - if any
A Person and all his children hierarchy - up to a specific depth
These should work.
The WHERE clauses are for eliminating subpaths. The answer for #4 cannot use the same WHERE clause, so the results will contain subpaths.
1.
MATCH p=(:Person{id:1})-[:HAS_CHILD*]->(c)
WHERE NOT (c)-[:HAS_CHILD]->()
RETURN NODES(p);
2.
MATCH p=(:Person { id:5 })<-[:HAS_CHILD*]-(ancestor)
WHERE NOT (ancestor)<-[:HAS_CHILD]-()
RETURN NODES(p);
3.
MATCH p=(p5:Person { id:5 })-[:HAS_CHILD*]-(p1:Person { id:1 })
RETURN NODES(p);
4. Using a depth up to 5:
MATCH p=(:Person{id:1})-[:HAS_CHILD*1..5]->(c)
RETURN NODES(p);
Using your datamodel consisting of (:Person)-[:HAS_CHILD]->(:Person) these queries should return the data you are looking for (let's also assume you have a unique name property on each Person node to facilitate a lookup by name, but you could also use any unique id/property):
A person and all his children
We can use a variable length path pattern here to match on patterns containing multiple HAS_CHILD relationships.
MATCH (p:Person)-[:HAS_CHILD*]->(child:Person)
WHERE p.name = "Bob Loblaw"
RETURN child;
A person and his parent hierarchy
Very similar to the above query, but we just reverse the relationship direction.
MATCH (p:Person)<-[:HAS_CHILD*]-(ancestor:Person)
WHERE p.name = "Bob Loblaw"
RETURN ancestor;
Relationship between two person - if any
We can use the shortestPath function to find the shortest path between two nodes in the graph. This query will return no rows if no path is found.
MATCH path=shortestPath((p:Person {name: "Bob Loblaw"})-[*]-(o:Person {name: "Louise Bluth"}))
RETURN path
A person and their child hierarchy - up to a specific depth
This query is very similar to the previous "person and all his children query" however we can specify bounds on the variable length path. Note: an upper bound should always be specified with variable length paths to avoid very long running queries.
MATCH (p:Person)-[:HAS_CHILD*1..5]->(child:Person)
WHERE p.name = "Bob Loblaw"
RETURN child;

Add Unique Nodes and relationship between them from Existing Setup in Neo4j

This is in continuation of the problem defined here
Query case-specific nodes in Neo4j
So the situation looks like the image below(please bear with the crappy image)
The blue links denotes the [:RELATES_TO] relationship with the number in black boxes denoting the value of Length property. Similar values also exists for all such other [:RELATES_TO] relationship which is not shown here.
Now I would like to find and create unique Nodes based on 'Name' property of Performer Nodes. Continuing with the example in the link there will be only 4 New Unique Nodes [A,B,C,D]. Lets Call them NewUniqueNodes with name as a property.
Then I would like to query each case in turn. Within each case, I need to query [:RELATES_TO] relationship in increasing order of Length property. For any such pair of nodes (x,y) I need to add a relationship [:FINALRESULT{strength:0}] from NewUniqueNode(Name:x) to NewUniqueNode(name:y) with strength being updated to (strength + value). The value is the number associated with value property of [:RELATES_TO] for the pair of nodes(x,y).
[Example and Expected Output]
In case1, the order of visiting nodes will be
Node(ID:3) to Node(ID:4)
Node(ID:1) to Node(ID:2)
Node(ID:1) to Node(ID:3)
On processing these nodes, the result would be
NewUniqueNode(name:A)-[:FINALRESULT{strength: 1}]-NewUniqueNode(name:D)
NewUniqueNode(name:A)-[:FINALRESULT{strength: 1}]-NewUniqueNode(name:B)
NewUniqueNode(name:B)-[:FINALRESULT{strength: 1}]-NewUniqueNode(name:A)
On processing the full set of cases(case1 + case2 + case3), the result would be something like
NewUniqueNode(name:A)-[:FINALRESULT{strength: 1}]-NewUniqueNode(name:D)
NewUniqueNode(name:A)-[:FINALRESULT{strength: 3}]-NewUniqueNode(name:B)
NewUniqueNode(name:B)-[:FINALRESULT{strength: 2}]-NewUniqueNode(name:A)
NewUniqueNode(name:C)-[:FINALRESULT{strength: 1}]-NewUniqueNode(name:B)
NewUniqueNode(name:A)-[:FINALRESULT{strength: 1}]-NewUniqueNode(name:A)
According to this Neo4j console setup, based on the previous question http://console.neo4j.org/r/vci9yd
I have the following query :
MATCH (n:Performer)
WITH collect(DISTINCT (n.name)) AS names
UNWIND names as name
MERGE (nn:NewUniqueNode {name:name})
WITH names
MATCH (c:Case)
MATCH (p1)-[r:RELATES_TO]->(p2)<-[:RELATES]-(c)-[:RELATES]->(p1)
WITH r
ORDER BY r.length
MATCH (nn1:NewUniqueNode {name:startNode(r).name})
MATCH (nn2:NewUniqueNode {name:endNode(r).name})
MERGE (nn1)-[rf:FINAL_RESULT]->(nn2)
SET rf.strength = CASE WHEN rf.strength IS NULL THEN r.value ELSE rf.strength + r.value END
Explanations :
First we match all performer nodes and collect the distinct name values in the names variable.
Secondly, we iterate the names with the UNWIND clause, creating a NewUniqueNode for each name in the names collection
Then we match all cases, within each case we look for the :RELATES_TO relationships that are inside this case and ordering them by the relationship length value
Then for each relationship found, we match the NewUniqueNode corresponding to the startNode name value, and same for the NewUniqueNode corresponding to the endNode name value
Lastly we merge the :FINAL RESULT relationship between those two unique nodes, we then set the strength property on the relationship depending of the :RELATES_TO relationship length value, for this part I guess you could do the same with ON CREATE and ON MATCH on the MERGE

How do I get all relationships between nodes on a path

I am trying to follow a certain relationship type and return all the nodes and (other) relationships on that path but not to follow paths through nodes that are not part of the path.
Below is the live query that I have set up to demonstrate.
http://console.neo4j.org/?id=b6sxoh
In the example I do not want the relationship through B->E->C to be included in the results because there is no 'depends_on' relationship between them.
Below is one of my many attempts... (also in the console).
START me=node:node_auto_index(name='A')
MATCH p=me-[d:depends_on*]->others
WITH me,others
MATCH p=me-[r*]-others
RETURN DISTINCT relationships(p);
I would love some help please!
One way to do this is to iterate through each pair of nodes on the matched path for the pattern "p=me-[d:depends_on*]->others", and find any other relationships between them.
START me=node:node_auto_index(name='A')
MATCH me-[:depends_on*0..]->(previous)-[:depends_on]->last
With previous, last
Match previous-[r]-last
Where type(r) <> 'depends_on'
Return r
Since each matched path for the pattern "me-[d:depends_on*]->others" is augmented with a new relationship as the last relationship, to iterate through all the relationships on the matched path is to iterate through each last relationship on the matched paths. So for each matched path, we capture the start node and the end node of the last relationship as "previous" and "last" and then find the relationships "r" between them, filter "r" with the "Where" clause based on the type of the relationship r, return only those relationships r that are not of the type "depends_on".

How retrieve all nodes linked by a relationship

I am using neo4j, I have nodes with two properties: name and id. I have an index on id.
I have relationships "CALL" with a property: "by_test". This property can take different value (id of any node).
Two nodes can have multiple CALL relationships with different by_test property value.
So let's say I have 1..N nodes linked by the same CALL.by_test property value.
Node1 -> Node2 -> Node3 -> .. -> Node N
How can I get all these nodes?
Do I need to put an Index on the relationship?
Do I have to create dynamic relationship? Instead of CALL.by_test=value, use value has a relationship.
Thanks!
Using Cypher, you could query for that list like this:
START n=node:node_auto_index(name="one")
MATCH p=(n)-[r:CALL*1..]->(m)
WHERE ALL(x in r WHERE x.by_test = 3)
RETURN n,m
In the MATCH you bind a term r to the CALL relationships, which you then use in the WHERE clause to check the by_test property of each.
As Michael Hunger noted, the r is a collection of relationships, so the WHERE needs to use ALL to check each of the relationships.

Resources