我有一个如下所示的 csv 文件:
美食 | 类别 | |
---|---|---|
0 | 橙色 | 水果 |
1 | 香蕉 | 水果 |
2 | 茄子 | 蔬菜 |
3 | 黄瓜 | 水果 |
4 | 胡萝卜 | 蔬菜 |
5 | 番茄 | 水果 |
6 | 番茄 | 蔬菜 |
7 | 黄瓜 | 蔬菜 |
8 | 洋葱 | 蔬菜 |
9 | 花椰菜 | 蔬菜 |
我如何绘制此图表,以便食物节点是唯一的,但水果类别不会因属于多个类别的食物而丢失?
到目前为止我已经使用了这段代码:
CREATE CONSTRAINT UniqueFood FOR (f:food) REQUIRE f.foodName IS UNIQUE
LOAD CSV FROM 'file:///food.csv' AS row
WITH toInteger(row[0]) AS foodId, row[1] AS foodName, row[2] AS foodType
MERGE (f:food {foodName: foodName})
SET f.foodName = foodName, f.foodType = foodType
RETURN f
LOAD CSV FROM 'file:///food.csv' AS row
WITH toInteger(row[0]) AS foodId, row[1] AS foodName, row[2] AS foodType
MERGE (t:foodType {foodType: foodType})
SET t.foodType = foodType
RETURN t
MATCH (f:food)
MATCH (t:foodType) WHERE f.foodType = t.foodType
CREATE (f)-[:BELONGS_TO]->(t)
但是对于黄瓜和西红柿,它只为它们分配了与一个类别的关系,而不是两者。
另外,如何删除标题行?当我将“WITH HEADERS”添加到上面的代码时,出现错误:“类型不匹配:映射键必须作为字符串给出,但为整数(第 2 行,第 20 列(偏移量:72)) “WITH toInteger(row[0]) AS foodId, row[1] AS foodName, row[2] AS foodType” “
要忽略标题行,您可以跳过它:
LOAD CSV ... AS row
WITH row SKIP 1
...
但是你不需要那样做。您应该保留
WITH HEADERS
选项,删除 WITH toInteger(row[0]) AS foodId, row[1] AS foodName, row[2] AS foodType
子句,然后在整个查询的其余部分使用 row.food
和 row.category
而不是 foodName
和 foodType
。 [旁白:标题行中的第一个标题是空字符串,因此不能用作 row
属性的名称。但是,由于您的查询实际上并未使用该列,因此这不会影响您。]
在这个答案的其余部分,我假设你使用你的标题:
LOAD CSV WITH HEADERS FROM 'file:///food.csv' AS row
MERGE (f:Food {name: row.food})
SET f.type = CASE WHEN f.type IS NULL THEN [row.category] ELSE f.type + row.category END
RETURN f
上面的查询会将
Food
的所有类别添加到类别列表中。
您不应将类别名称保留在
Food
节点中,并且还与作为单独节点的这些类别有关系。做一个或另一个。
如果您想创建与唯一
FoodType
节点的关系:
LOAD CSV WITH HEADERS FROM 'file:///food.csv' AS row
MERGE (f:Food {name: row.food})
MERGE (t:FoodType {type: row.category})
MERGE (f)-[:BELONGS_TO]->(t)