I am a Neo4J newbie and I have a simple CSV with source and dest IPs. I'd like to create a relationship between nodes with the same labels.
Something like ... source_ip >> ALERTS >> dest_ip, or the reverse.
"dest_ip","source_ip"
"130.102.82.16","54.231.19.32"
"130.102.82.116","114.30.64.11"
"130.102.82.116","114.30.64.11"
...
LOAD CSV WITH HEADERS
FROM "file:///Users/me/Desktop/query_result.csv" AS csvLine
CREATE (alert:Alert { source_ip: csvLine.source_ip, dest_ip: csvLine.dest_ip})
MATCH (n:Alert) RETURN n LIMIT 25
dest_ip 130.102.82.16 source_ip 54.231.19.32
....
This works fine. My question is how I create the relationship between the labels inside the alerts? I've tried and failed a slew of times. I'm guessing I need to set up separate Nodes for Source and Dest and then link them, just unsure how.
Thanks in advance!
Peace,
Tom
First create a constraint like this, to guarantee uniqueness and speed up the MERGE operation.
CREATE CONSTRAINT ON (a:Alert) ASSERT a.ip IS UNIQUE;
You can use as many CREATE statements as you want, and then MERGE the relationship, like this:
LOAD CSV WITH HEADERS
FROM "file:///Users/me/Desktop/query_result.csv" AS csvLine
MERGE (node1:Alert { ip: csvLine.source_ip })
MERGE (node2:Alert { ip: csvLine.dest_ip })
MERGE (node1)-[r:ALERT]->(node2)
By the by, I'd recommend using MERGE in most places to make sure you don't end up creating duplicates. In this file, a certain IP address might be listed many times, you don't want a new node each time it's created, you probably want all references under that one IP address, hence MERGE here instead of CREATE
Assuming that your graph model is something like
(:source)-[:ALERT]->(:Destination)
The following Cypher query will create that relationship
LOAD CSV WITH HEADERS FROM "file:///Users/me/Desktop/query_result.csv" AS csvLine
CREATE (source:Source { ip: csvLine.source_ip })-[:ALERTS]->(dest:Destination { ip: csvLine.dest_ip})
Related
I’m desperately trying to understand how to consolidate nodes in Neo4J for a more streamlined relationship.
I have a dataset with four columns: Person_1_ID, Person_1_Name, Person_2_ID, Person_2_Name
How do you consolidate IDs when they exist in two columns so that you only show one node?
For example:
My dataset looks like this:
If I do a simple match and merge like this:
LOAD CSV WITH HEADERS FROM 'file:///users.csv' AS row
MATCH (Person_1:Person_1 {Person_1_ID: row.Person_1_ID})
MATCH (Person_2:Person_2 {Person_2_ID: row.Person_2_ID })
MERGE (Person_2)-[pr:REFERRING]->(Person_1);
It produces this:
I'm trying to merge on names/IDs so that the relationships look like this:
Desperately trying to understand how you merge nodes properly here so that the relationships are consolidated. Any guidance and code example is greatly appreciated!
Doug
You have a couple of issues:
In your initial node import, don't use Person_1 and Person_2 node labels. Just stick with a single node label Person. The same goes for person id node property. If I were you, I would just delete existing graph and use the following Cypher to produce the desired results:
LOAD CSV WITH HEADERS FROM 'file:///users.csv' AS row
MERGE (Person_1:Person {id: row.Person_1_ID})
MERGE (Person_2:Person {id: row.Person_2_ID })
MERGE (Person_2)-[pr:REFERRING]->(Person_1);
I am trying to create a relationship between two existing nodes. I am reading the node ID's from a CSV and creating the relationship with the following query:
LOAD CSV WITH HEADERS FROM "file:///8245.csv" AS f
MATCH (Ev:Event) where id(Ev) =f.first
MATCH (Ev_sec:Event) where id(Ev_sec) = f.second
WITH Ev, Ev_sec
MERGE (Ev) - [:DF_mat] - > (Ev_sec)
However, it is not changing anything the database. How can I solve this problem?
Thanks!
I solved the problem. So, I again queried for the ID(node) and this time I exported them as a string (by using toString(ID(node)) ). Then while loading to the database, I converted them to Integer. The query is as follows:
LOAD CSV WITH HEADERS FROM "file:///8245_new.csv" AS csvLine
match (ev:Event) where id(ev)=toInteger(csvLine.first)
match (ev_sec:Event) where id(ev_sec)=toInteger(csvLine.second)
merge (ev)-[:DF_mat]-> (ev_sec)
Apologies as I am new to neo4j and struggling with what I imagine is a very simple example.
I would like to model an org chart which I have stored as a csv like so
id,name,manager_id
1,allan,2
2,bob,4
3,john,2
4,sam,
5,Jim,2
Note that Bob has 3 direct reports and Bob reports into Sam who doesn't report into anyone.
I would like to produce a graph which shows the management chain. I have tried the following, but it produces relationships which are disjoint from the people:
LOAD CSV WITH HEADERS FROM "file///employees.csv" AS csvLine
CREATE (p:Person {id: csvLine.id, name: csvLine.name})
CREATE (p)-[:MANAGED_BY {manager: csvLine.manager_id}]->(p)
This query creates a bunch of self-referencing relationships. Is there anyway to populate the graph with one command over the single csv? I must be missing something and any help is appreciated. Thanks
I think this is what you are looking for.
In your query tou are creating a relationship between p and p thus the self referencing relationships.
I added a coalesce statement to deal with people that do not have a manager_id value. THis way Sam can report to himself.
LOAD CSV WITH HEADERS FROM "file:///employees.csv" AS csvLine
// create or match the person in the left column
MERGE (p:Person {id: csvLine.id })
// if they are created then assign their name
ON CREATE SET p.name = csvLine.name
// create or match the person/manager in the right column
MERGE (p1:Person {id: coalesce(csvLine.manager_id, csvLine.id) })
// create the reporting relationship
CREATE (p)-[:MANAGED_BY]->(p1)
I have the following file A.csv
"NODE","PREDECESSORS"
"1",""
"2","1"
"3","1;2"
I want to create with the nodes: 1,2,3 and its relationships 1->2->3 and 1->3
I have already tried to do so:
LOAD CSV WITH HEADERS FROM 'file:///A.csv' AS line
CREATE (:Task { NODE: line.NODE, PREDECESSORS: SPLIT(line.PREDECESSORS ';')})
FOREACH (value IN line.PREDECESSORS |
MERGE (PREDECESSORS:value)-[r:RELATIONSHIP]->(NODE) )
But it does not work, that is, it does not create any relationship.
Please, might you help me?
The problem is in your MERGE:
MERGE (PREDECESSORS:value)-[r:RELATIONSHIP]->(NODE)
This is merging a :value labeled node and assigning it to the variable PREDECESSORS, which can't be what you want to do.
A better approach would be not save the predecessor data in the node, just use that to match on the relevant nodes and create the relationships.
It will also help to have an index on :Task(NODE) so your matches to the predecessors are quick.
Remember also that cypher queries do not process the entire query for each row, but rather each operation in the query is processed for each row, so once the CREATE executes, all nodes will be created, there's no need to use MERGE the predecessor nodes.
Try something like this:
LOAD CSV WITH HEADERS FROM 'file:///A.csv' AS line
CREATE (node:Task { NODE: line.NODE})
WITH node, SPLIT(line.PREDECESSORS, ';') as predecessors
MATCH (p:Task)
WHERE p.NODE in predecessors
MERGE (p)-[:RELATIONSHIP]->(node)
In shortest way my problem is below:
I need to get from the following csv file
(https...)drive.google.com/file/d/0B-y9nPaqlH6XdXZsYzAwLThacTg/view?usp=sharing
The following data-structure in neo4j (Using cypher import):
https://drive.google.com/file/d/0B-y9nPaqlH6XdlZHM216eDRSX3c/view?usp=sharing
Instead of:
[https://drive.google.com/file/d/0B-y9nPaqlH6XdE9vZ0gyNU1lR0U/view?usp=sharing]
The longer interpretation:
I thought, the solution of my problem is just need to understand to (un)bound elements.
But I tried many times, in many ways (with(out) creating single nodes first, or in empty database):
LOAD CSV with headers FROM "file:///C:/Users/user/Desktop/neo4j help/calling.csv"
AS csvLine
MERGE (u1:Person { number:(csvLine.A), name:(csvLine.name_A)}) MERGE (u2:Person { number:(csvLine.B), name:(csvLine.name_B)})
MERGE (u1:Person { number:(csvLine.A), name:(csvLine.name_A)})-[c:called]->(u2:Person { number:(csvLine.B), name:(csvLine.name_B)})
RETURN u1.name,c,u2.name
I got instead of wondered results just error message:
Can't create u1 with properties or labels here. It already exists in
this context
And without „pre-merging“ the nodes, I have the results above (in the pink picture)
What do I need to obtain the wanted result (in the first picture)?
You don't need to redefine the u1 and u2 nodes. Just reuse the identifiers and MERGE the relationship :
LOAD CSV with headers FROM "file:///C:/Users/user/Desktop/neo4j help/calling.csv"
AS csvLine
MERGE (u1:Person { number:(csvLine.A), name:(csvLine.name_A)})
MERGE (u2:Person { number:(csvLine.B), name:(csvLine.name_B)})
MERGE (u1)-[c:CALLED]->(u2)
RETURN u1.name,c,u2.name
Nb: I think your images are both the same, and you can post them in your questions, many people will skip your question because they need to open 2 or 3 more browser windows