Establish relationship among nodes in Neo4j - neo4j

I am new to Neo4j. I have customer and product data into Neo4j. While loading I have not established any relationship among them. Now I want to establish relation among them like:
create (Customer1)-[:bought]->(Item1),(Customer1)-[:bought]->(Item2);
After I execute this statement it says Relationship established but as and when I try to access it like:
start n=node(*) match (n)-[:bought]->(items) where n.NodeName! = "Customer1" return items;
it says 0 rows. I think if it successfully establishes relationship it should give me 2 items, Item1 & Item2.
Any idea?

Apparently, you didn't set NodeName for your Customer1 node in your creation query. Try to modify it like this:
create (Customer1 { NodeName:'Customer1' }), (Item1 { NodeName:'Item1' }), (Item2 { NodeName:'Item2' }), (Customer1)-[:bought]->(Item1), (Customer1)-[:bought]->(Item2);
Then your second query should return 2 rows as you expected.
Update:
Ok, I didn't understand the question correctly. So, you want to establish a relationship between already existing nodes. Then try this:
start Customer1=node:node_auto_index(NodeName='Customer1'), Item1=node:node_auto_index(NodeName='Item1'), Item2=node:node_auto_index(NodeName='Item2')
create (Customer1)-[:bought]->(Item1),(Customer1)-[:bought]->(Item2);

Related

Correct order of operations in neo4j - LOAD, MERGE, MATCH, WITH, SET

I am loading simple csv data into neo4j. The data is simple as follows :-
uniqueId compound value category
ACT12_M_609 mesulfen 21 carbon
ACT12_M_609 MNAF 23 carbon
ACT12_M_609 nifluridide 20 suphate
ACT12_M_609 sulfur 23 carbon
I am loading the data from the URL using the following query -
LOAD CSV WITH HEADERS
FROM "url"
AS row
MERGE( t: Transaction { transactionId: row.uniqueId })
MERGE(c:Compound {name: row.compound})
MERGE (t)-[r:CONTAINS]->(c)
ON CREATE SET c.category= row.category
ON CREATE SET r.price =row.value
Next I do the aggregation to count total orders for a compound and create property for a node in the following way -
MATCH (c:Compound) <-[:CONTAINS]- (t:Transaction)
with c.name as name, count( distinct t.transactionId) as ord
set c.orders = ord
So far so good. I can accomplish what I want but I have the following 2 questions -
How can I create the orders property for compound node in the first step itself? .i.e. when I am loading the data I would like to perform the aggregation straight away.
For a compound node I am also setting the property for category. Theoretically, it can also be modelled as category -contains-> compound by creating Categorynode. But what advantage will I have if I do it? Because I can execute the queries and get the expected output without creating this additional node.
Thank you for your answer.
I don't think that's possible, LOAD CSV goes over one row at a time, so at row 1, it doesn't know how many more rows will follow.
I guess you could create virtual nodes and relationships, aggregate those and then use those to create the real nodes, but that would be way more complicated. Virtual Nodes/Rels
That depends on the questions/queries you want to ask.
A graph database is optimised for following relationships, so if you often do a query where the category is a criteria (e.g. MATCH (c: Category {category_id: 12})-[r]-(:Compound) ), it might be more performant to create a label for it.
If you just want to get the category in the results (e.g. RETURN compound.category), then it's fine as a property.

Creating a relationship with an atribute - Neo4j

I'm learning about neo4j and I have the following question.
I have two groups of nodes, the first one is called Workers who have an ID and the name of the worker.
On the other hand there is another group of nodes, called products, which apart from the id, has the following attributes; price, name.
I want to make a relationship called "manipulate" where I relate a worker to the product that he is going to manipulate.
For this I have a trabajaensector.csv file which relates the workers by id, along with the products they are going to manipulate, also by id.
This is its form:
id1,id2,sector
1,1,fruteria
2,2,fruteria
3,2,fruteria
4,7,panaderia
5,5,fruteria
6,5,fruteria
7,9,bebidas
8,9,bebidas
9,10,bebidas
10,10,bebidas
11,3,pescaderia
12,8,panaderia
13,7,panaderia
14,9,bebidas
15,10,bebidas
16,4,pescaderia
17,2,fruteria
18,4,pescaderia
In summary, id1 (worker) manipulates id2 (product) and its sector is "fruteria/pescaderia/panaderia o bebida"
This is my CQL for creating manipulate relationship:
LOAD CSV WITH HEADERS FROM "file:///trabajaensector.csv" AS csvLine
MATCH(w:Worker),(p:Product) where w.id= toInt(csvLine.id1) and p.id=
toInt(csvLine.id2) create (w)-[sect:trabajasec]->(p) return sect
Here is my problem, the relationship is apparently creating well, however I am losing that third "sector" data, which indicates the sector where the worker works by manipulating that product.
For example, the relationship for a worker named Juan who manipulates apples should have in the relation the variable / attribute "fruteria" or for fish "pescaderia".
Any idea of how to properly include that data in the relationship and how to recover it?
You can add a sector property to the trabajasec relationships:
LOAD CSV WITH HEADERS FROM "file:///trabajaensector.csv" AS csvLine
MATCH (w:Worker), (p:Product)
WHERE w.id = TOINT(csvLine.id1) AND p.id = TOINT(csvLine.id2)
CREATE (w)-[sect:trabajasec {sector: csvLine.sector}]->(p)
RETURN sect;
To use the above query, you should first delete the trabajasec relationships created by your earlier LOAD CSV query.

How to create a relation between two node having same node name in neo4j

I want to create a friends relation between abcd node and vbnm node having same node-name - Student
neo4j graph database visualization
I execute the following query, It doesn't show me any error but this query doesn't create any relation
match(Student:Stu),(Student:Stu)where Student.name="abcd" AND Student.name="vbnm" create(Student)-[fr:friends]->(Student)
You need use different variable name:
match(Student1:Stu),(Student2:Stu)
where Student1.name="abcd" AND
Student2.name="vbnm"
create(Student1)-[fr:friends]->(Student2)
I think you are confused by the syntax a little bit. Let me give you an example of a MATCH query syntax.
MATCH (variable1:Label),(variable2:Label) where variable1.foo = variable2.foo
You mixed label and variable in your query and each entity should have its own variable (variable1 and variable2) so you can interact with them.
So in your case the optimal query looks something like:
MATCH (s1:Student),(s2:Student ) where s1.name="abcd" AND s2.name="vbnm"
CREATE (s1)-[:friends]->(s2)
Note that you do not need to assign a variable to [:friends] relationship as you do not interact with it later in the same query.

Neo4j display only one node for 1 to many relationship

i'm trying to solve a problem of the 1: many relationship display in neo4j. My dataset is as below
child,desc,type,parent
1,PGD,Exchange,0
2,MSE 1,MSE,1
3,MSE 2,MSE,1
4,MSE 3,MSE,1
5,MSE 4,MSE,1
6,BRAS 1,BRAS,2
6,BRAS 1,BRAS,3
7,BRAS 2,BRAS,4
7,BRAS 2,BRAS,5
10,NPE 1,NPE,6
11,NPE 2,NPE,7
12,OLT,OLT,10
12,OLT,OLT,11
13,FDC,FDC,12
14,FDP,FDP,13
15,Cust 1,Customer,14
16,Cust 2,Customer,14
17,Cust 3,Customer,14
LOAD CSV WITH HEADERS FROM 'file:///FTTH_sample.csv' AS line
CREATE(:ftthsample
{child_id:line.child,
desc:line.desc,
type:line.type,
parent_id:line.parent});
//Relations
match (child:ftthsample),(parent:ftthsample)
where child.child_id=parent.parent_id
create (child)-[:test]->(parent)
//Query:
MATCH (child)-[childrel:test*]-(elem)-[parentrel:test*]->(parent)
WHERE elem.desc='FDP'
RETURN child,childrel,elem,parentrel
It returns a display as below.
I want the duplicate nodes to be displayed as one. Newbie with Neo4J. Can anyone of the experts help please?
This seems like an error in your graph creation query. You have a few lines in your query specifying the same node multiple times, but with multiple parents:
6,BRAS 1,BRAS,2
6,BRAS 1,BRAS,3
I'm guessing you actually want this to be a single node, with parent relationships to nodes with the given parent ids, instead of two separate nodes.
Let's adjust your import query. Instead of using a CREATE on each line, we'll use MERGE, and just on the child_id, which seems to be your primary key (maybe consider just using id instead, as a node can have an id on its own, without having to consider the context of whether it's a parent or child). We can use the ON CREATE clause after MERGE to add in the remaining properties only if the MERGE resulted in node creation (instead of matching to an existing node.
That will ensure we only have one node created per child_id.
Rather than having to rematch the child, we can use the child node we just created, match on the parent, and create the relationship.
LOAD CSV WITH HEADERS FROM 'file:///FTTH_sample.csv' AS line
MERGE(child:ftthsample {child_id:line.child})
ON CREATE SET
child.desc = line.desc,
child.type = line.type
WITH child, line.parent as parentId
MATCH (parent:ftthsample)
WHERE parent.child_id = parentId
MERGE (child)-[:test]->(parent)
Note that we haven't added line.parent as a property. It's not needed, since we only use that to create relationships, and after the relationships are there, we won't need those again.

NEO4J WEB ADMIN INTERFACE SOME QUESTIONS

I apologize now for my bad English. I'm Italian
I'm just using Neo4j for the thesis, but I still have doubts about the multi use.
1) I have created from the web interface, two nodes. I realized that Neo4j has given these indices 0 and 1 (for research). Now suppose that I was wrong and I have to delete the node with index 1 .. Once deleted do I create a new one and the system puts index 2.
Practically now the first node with index 0 and the second node with index 2 But I want the second node still has index 1 (basically I want to use the index of the first, as I do?)
2) The same problem with the relationship between two nodes. if I'm wrong to create it, the gate and I create another, I lose the index of the one deleted.
3) If I have to create a relationship between 2 nodes with the double arrow, as I do.
I saw that every arrow must have a label, so if I create a relationship between 1 and 2, and a relationship between 2 and 1, you get the double arrow, but with two labels and does not suit me. Thank you for your help
sorry for my very bad English
You should really try to use your own IDs or unique identifier for your nodes, then you can disregard the internal node IDs all together.
If you begin with this Cypher statement in a new database (you only have to set it once),
CREATE CONSTRAINT ON (node:MyNodeLabel) ASSERT node.myid IS UNIQUE
then you can create nodes and relationship like this,
CREATE (a:MyNodeLabel { myid : 0 })
CREATE (b:MyNodeLabel { myid : 1 })
CREATE (a)-[r:RELTYPE]->(b)
or if you do not write the create statements in the same transaction,
CREATE (:MyNodeLabel { myid : 2 })
CREATE (:MyNodeLabel { myid : 3 })
then later,
MATCH (a:MyNodeLabel { myid : 2 }), (b:MyNodeLabel { myid : 3 })
CREATE (a)-[r:RELTYPE]->(b)
or create two nodes and a relationship at the same time
MERGE (:MyNodeLabel { myid : 4 })-[r:RELTYPE]->(:MyNodeLabel { myid : 5 })
You can of course change MyNodeLabel and myid to any identifier you like.
The problem you have with the relationship labels is purely visual or do I misunderstand you?
You know that you can traverse relationships in any direction so maybe you do not need two relationships?
Here is the documentation for Cypher if you have missed it, http://docs.neo4j.org/chunked/stable/.
ok. sorry. I return at home today.... Another question. when you create a relationship with a label on the arrow. how do sometime in the future to change the label
without delete the relationship? is possible?
Q ok. sorry. I return at home today.... Another question. when you create a relationship with a label on the arrow. how do sometime in the future to change the label without delete the relationship? is possible?
ANS Yes,
You can do that easily you can server for the node and remove label only from the node it will not impact the relation ship , but i will suggest you to assing another one if that was the only label on the node so you can group it properly.
match(n:User{Id:1})
remove n:User set n:DeletedUser
return n

Resources