Reputation: 953
How can one set both the property name and its value loading a tall skinny csv file? The csv file would contain only 3 columns, node name (id), property name (p) and property value (v). A node with to properties would therefore correspond to 2 lines.
LOAD CSV... row
MERGE (n) WHERE n.Name = row.id
SET n.{row.p} = row.v
This syntax doesn't exit it's just to explain what I'd like to do. Is there a way to do such a thing in cypher? That be really useful rather than having to pivot data first.
A file contains definitions for person nodes:
Name,Age
A,25
B,34
A second file contains properties for specific nodes, one property per line
Name,property_name,property_value
A,weight,64
A,height,180
B,hair color,blond
I'd like to update nodes A and B and set additional properties based on the second file.
As mentioned below, one possibility is to create (:Data) nodes containing one property each, and link them person nodes
CREATE (p) -[:hasProperty]-> (:Data {Name: row.property_name, Value: row.property_value})
However, this might not be very efficient and extracting person nodes and properties gets much more complex.
MATCH (p:Person) --> (d:Data)
RETURN {name: p.name, age: p.age, property_names: collect(d.Name), property_values: collect(d.Value)}
Graal could either be to set property name dynamically on load, or a pivot function to return data properties on nodes.
Upvotes: 0
Views: 2121
Reputation: 20185
You can not assign a property key dynamically from parameters, however since the row is a map, you can set all the row as properties on the node if it is ok for you :
LOAD CSV ... AS row
MERGE (n:Label {Name: row.id})
SET n += row
EDIT
Based on your edit, for your second file, if you don't have too much different values like weight, height, etc.. you can create a conditional collection, example :
LOAD CSV WITH ... AS row
WITH row, CASE row.property_name WHEN weight THEN [1] ELSE [] END as loopW
UNWIND loopW as w
MATCH (p:Person {name: row.Name})
SET p.weight = row.property_value
WITH row, CASE row.property_name WHEN height THEN [1] ELSE [] END as loopH
UNWIND loopH as h
MATCH (p:Person {name: row.Name})
SET p.height = row.property_value
...
Upvotes: 0