NEO4J WEB ADMIN INTERFACE SOME QUESTIONS - neo4j

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

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.

Set propertie to related nodes that are already created in Neo4j

I'm using py2neo in Python to run my Cypher queries.
I'm trying to create Person nodes and relationships between then.
My DataFrame is like this:
df
>>> id_user name follows.profiles
a_123 Mc Marcão <3 [a_134, a_934, a_145, a_988]
a_234 john a_111
a_934 alice NaN
: : :
: : :
So here we can see that a Person can follows multiple persons, because follows.profiles is a list.
So this is what I did:
for index, row in df.iterrows():
graph.run('''
UNWIND $label3 as follow_profile
MERGE (p1:Profile { id_user: $label1, name: $label2 })
MERGE (p1)-[:FOLLOWS]->(p2:Profile { id_user: follow_profile })
''', parameters = {'label1': row['id_user'],
'label2': row['name'],
'label3': row['follows.profiles']
})
So the nodes are created and their relationships too.
Now I want to set labels to the nodes relateds. How can I do this?
All the nodes you created already have a Profile label. But the neo4j Browser does not show the labels since normally you want identifying information to display for each node. However, the Browser does allow you to specify a different color for each label.
See the documentation for how to do that.

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.

Set degree of Nodes

I have a graph in which I am keeping the degree of a node as a property called "degree" in the node.
What I need is when I create an edge between two nodes, I need to increment the degree of the two nodes.
For creating unique edges I am using "CREATE UNIQUE" for the edges. So if I need to increment the property "degree" of the corresponding nodes, I need to use "ON CREATE" and "ON MATCH" as it is for "MERGE".
But I can't use the ON CREATE and ON MATCH with CREATE UNIQUE. So whats the proper way of using ON CREATE and ON MATCH with CREATE UNIQUE?
This is the way I am trying:
MATCH (n1:PER {Node_Id:"X"}), (n2:PER {Node_Id:"Y"}) WHERE n1.Node_Id<>n2.Node_Id CREATE UNIQUE (n1)-[r:PER_PER {Doc_Id:"st_new", Event_Class:"EC_1", Event_Instance:"EI_1"}]-(n2) ON CREATE SET n1.degree = n1.degree + 1, n2.degree = n2.degree + 1
Not sure why you want to store the degree as a property. Neo4j has a getDegree() function on API level, see http://neo4j.com/docs/stable/javadocs/org/neo4j/graphdb/Node.html#getDegree(). Cypher is not yet using this everywhere possible but for some patterns it already does.
Nevertheless to answer your question: just use MERGE instead of CREATE UNIQUE for eventually establishing the relationship:
MATCH (n1:PER {Node_Id:"X"}), (n2:PER {Node_Id:"Y"})
WHERE n1.Node_Id<>n2.Node_Id
MERGE (n1)-[r:PER_PER {Doc_Id:"st_new", Event_Class:"EC_1", Event_Instance:"EI_1"}]-(n2)
ON CREATE SET n1.degree = n1.degree + 1, n2.degree = n2.degree + 1
If you do have a good reason to store node degrees as a property, please have a look at one of our modules called RelCount, which has been build exactly for what you need to do. It is described in detail in my thesis.
However, as Stefan points out, have a go with getDegree() first and only if that isn't fast enough, or you need to get degree based on some relationship property values as well, use RelCount.

Establish relationship among nodes in 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);

Resources