Trying to create a relationships between nodes with 2 different properties names but some of them have the same value - neo4j

Hey all a beginner neo4j student here o/
I created 40 nodes
20 :EMPLOYEE and 20 :ORGANIZATION nodes
Employee nodes have the owns_organizationNr property
Organization nodes have the ownedBy_organizationNr property
some of those nodes have the same value and I tried the query below
to create relationships between those who match by the property value and insert the
n1.owns_organizationNr property and value into to new relationship but something is missing
can you guys help me, please?
MATCH (n1:EMPLOYEE) , (n2:ORGANIZATION)
WHERE
HAS(n1.owns_organizationNr) AND HAS(n2.ownedBy_organizationNr) AND n1.owns_organizationNr = n2.ownedBy_organizationNr
CREATE (n1) -[:OWNS_ORG{n1.owns_organizationNr}]->(n2)

The query is doing a cartesian product so it is resulting to a lot of rows. You can use below query. Also, there is a typo error on the CREATE statement. I also fix it in the last line.
MATCH (n1:EMPLOYEE) WHERE n1.owns_organizationNr is not null
WITH n1
MATCH (n2:ORGANIZATION)
WHERE n2.ownedBy_organizationNr is not null AND n1.owns_organizationNr = n2.ownedBy_organizationNr
CREATE (n1) -[:OWNS_ORG{owns_organizationNr: n1.owns_organizationNr}]->(n2)
Sample result:

Related

How to find what relations exists between 2 nodes 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

How to add collection of values for a bidirectional relationship properties in neo4j?

I am creating 2 nodes in neo4j with a directional properties like below:
both employees are calling each other and they are connected with each other by CALLED relationship..
MATCH (e1:EMP),(e2:EMP) WHERE e1.NUMBER='200' AND e2.NUMBER='100' MERGE (e1)-[r:CALLED]->(e2) SET r.DURATION = ['233']
and my result is like below.
when I am creating a relation in revrese direction :
MATCH (e1:EMP),(e2:EMP) WHERE e1.NUMBER='100' AND e2.NUMBER='200' MERGE (e1)-[r:CALLED]->(e2) SET r.DURATION = "235" +r.DURATION[0..]
and my result is showing something strange
How can I add two properties in a collection so that it should look like
The concept of bidirectional exists only when querying. When creating relationships, every relationship must have a direction. What you have two different relations, one in each direction.
The relation from emp 200 to 100 has a property called duration with value ['233'].
Next, when you create a relation in the opposite direction from emp 100 to 200, this relation is a new one, it has nothing to do with the earlier relation except that the participating nodes are the same.
In this query
MATCH (e1:EMP),(e2:EMP)
WHERE e1.NUMBER='100' AND e2.NUMBER='200'
MERGE (e1)-[r:CALLED]->(e2) SET r.DURATION = "235" +r.DURATION[0..]
r.DURATION is null because the DURATION property does not yet exist on the relationship r from e1(100) to e2(200).
If you want to add durations to the relationship in a specific direction, you could use something like this
MATCH (e1:EMP),(e2:EMP)
WHERE e1.number='100' AND e2.number='200' MERGE (e1)-[r:CALLED]->(e2)
SET r.DURATION =["335"]+coalesce(r.DURATION,[])
Note that this inserts new duration values into the array on the relationship from emp 100 to 200. The values from emp 200 to 100 are unread and unmodified. If you wish to append values from the relationship in the opposite direction, you'll have to match it first to get the DURATION property. Doing this implies the same property value on the relation in both directions, and then I'd question why you need two relations instead of one.
If the direction is of no importance, use a single relation between e1 and e2.

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

Cypher Query isn't returning any Nodes

I have some problems to receive some Nodes and relationships and I hope someone here can actually help to find my mistake!
Broken down:
I have three nodes:
a Node labelled :Person with the property firstname
a Node labelled :Event
a Node labelled :Question with the property id
Basically the Relationship are as following:
(p:Person)-[:CREATED_EVENT]->(e:Event)
and
(e:Event)-[:ANSWERED]->(q:Question)
I tried to query:
MATCH
(p:Person)-[:CREATED_EVENT]->(e:Event)<-[:ANSWERED]-(q:question)
WHERE p.firstname = "foo" AND q.id=2
RETURN p, e, q;
But my query is not returning any Node at all.
I haven't created any Indexes yet. But if I read correctly you can only create Indexes on properties and it will only speed up your queries.
Can anybody spot a mistake?
Thank you for your help!
Assuming your data is correct, then it looks like you've got the wrong direction specified on the ANSWERED relation:
MATCH
(p:Person)-[:CREATED_EVENT]->(e:Event)-[:ANSWERED]->(q:question)
WHERE p.firstname = "foo" AND q.id=2
RETURN p, e, q;
If you still don't get results, would be good to create a sample graph demonstrating the problem at http://console.neo4j.org/?init=0

Cypher - multiple relationships with same label, i want to delete just one

I have the following schema:
(Node a and b are identified by id and are the same in both relationships)
(a)-[r:RelType {comment:'a comment'} ]-(b)
(a)-[r:RelType {comment:'another comment'} ]-(b)
So i have 2 nodes, and an arbitrary number of relationships between them. I want to delete just one of the relationships, and i don t care which one. How can i do this?
I have tried this, but it does not work:
match (a {id:'aaa'})-[r:RelType]-(b {id:'bbb'}) where count(r)=1 delete r;
Any ideas?
Here is the real-world query:
match (order:Order {id:'order1'}),(produs:Product {id:'supa'}),
(order)-[r:ordprod {status:'altered'}]->(produs) with r limit 1 set r.status='alteredAgain'
return (r);
The problem is Chypher says
Set 1 property, returned 1 row in 219 ms
, but when i inspect the database, it turns out all relationships have been updated.
Use the following:
match (a {id:'aaa'})-[r:RelType]-(b {id:'bbb'})
with r
limit 1
delete r
I tried to implement data structure like your's (Mihai's). and gone with both solutions; i.e., Stefan's and Sumit's. Stefan's solution is working at my side. Mihai, are you still facing any problems?
Hope this helps(As per my understanding you are trying to modify a relationship between two given nodes)
MATCH (order:Order {id:'order1'})-[r:ordprod {status:'altered'}]->(produs:Product {id:'supa'})
WITH order,r,produs
LIMIT 1
DELETE r
WITH order,produs
CREATE (order:Order {id:'order1'})-[r:ordprod {status:'alteredAgain'}]->(produs:Product {id:'supa'})
return (r);
And the reason for all your relationships getting updated is that after your WITH clause you are passing only r ie the relationship which may be same between all such nodes of label Order and Product. So when you do r.status = 'alteredagain' it changes all the relationships instead of changing between those two specific nodes that you matched in the beginning of your cypher query. Pass them too in the WITH and it will work fine!

Resources