Neo4j Cypher 在唯一约束下加载 CSV 失败
Neo4j Cypher Load CSV Failure on Unique Constraint
我在使用 Cypher LOAD CSV
命令将大量数据导入 Neo4j 实例时遇到问题。我试图加载大约 253k 个用户记录,每个记录都有一个唯一的 user_id。我的第一步是在 tje 标签上添加一个唯一约束,以确保用户只 运行 一次
CREATE CONSTRAINT ON (b:User) ASSERT b.user_id IS UNIQUE;
然后我尝试 运行 加载 CSV 并定期提交以提取此数据。
此查询失败,所以我尝试在设置前合并用户记录
USING PERIODIC COMMIT 1000
load csv with headers from "file:///home/data/uk_users.csv" as line
match (t:Territory{territory:"uk"})
merge (p:User {user_id:toInt(line.user_id)})-[:REGISTERED_TO]->(t)
set p.created=toInt(line.created), p.completed=toInt(line.completed);
修改定期提交值没有任何区别,返回相同的错误。
USING PERIODIC COMMIT 1000
load csv with headers from "file:///home/data/uk_buddies.csv" as line
match (t:Territory{territory:"uk"})
merge (p:User {user_id:toInt(line.user_id), created:toInt(line.created), completed:toInt(line.completed)})-[:REGISTERED_TO]->(t);
我收到以下错误:
LoadCsvStatusWrapCypherException: Node 9752 already exists with label Person and property "hpcm_uk_buddy_id"=[2446] (Failure when processing URL 'file:/home/data/uk_buddies.csv' on line 253316 (which is the last row in the file). Possibly the last row committed during import is line 253299. Note that this information might not be accurate.)
数字似乎大致吻合,CSV 文件总共包含 253315 条记录。 periodic commit好像也没有生效,节点数returns只有5446行
neo4j-sh (?)$ match (n) return count(n);
+----------+
| count(n) |
+----------+
| 5446 |
+----------+
1 row
768 ms
如果这个 ID 在 CSV 文件中只有大约 5000 行,我可以理解节点数不正确。但是我可以使用任何技术或命令来成功导入吗?
我认为您正在成为 MERGE
常见错误的牺牲品。相对于密码查询,说真的,这就像我关于密码常见问题的十大常见问题解答。看你在干嘛:
USING PERIODIC COMMIT 1000
load csv with headers from "file:///home/data/uk_buddies.csv" as line
match (t:Territory{territory:"uk"})
merge (p:User {user_id:toInt(line.user_id), created:toInt(line.created), completed:toInt(line.completed)})-[:REGISTERED_TO]->(t);
最后一次合并匹配整个关系的方式 merge works,而不仅仅是用户节点。因此,您可能正在创建不应该创建的重复用户。当您 运行 此合并时,即使具有这些确切属性的用户已经存在,与 t
节点的关系也不存在,因此它会尝试创建具有这些属性的新用户节点,以连接t
,这不是你想要的。
解决办法是先单独合并用户,再单独合并关系路径,像这样:
USING PERIODIC COMMIT 1000
load csv with headers from "file:///home/data/uk_buddies.csv" as line
match (t:Territory{territory:"uk"})
merge (p:User {user_id:toInt(line.user_id), created:toInt(line.created), completed:toInt(line.completed)})
merge (p)-[:REGISTERED_TO]->(t);
注意最后的两个合并。一个只创建用户。如果用户已经存在,它不会尝试创建副本,并且您应该可以接受您的约束(假设没有两个用户具有相同的 user_id,但创建的值不同)。仅合并用户后,再合并关系。
第二个查询的最终结果相同,但不应创建重复用户。
我在使用 Cypher LOAD CSV
命令将大量数据导入 Neo4j 实例时遇到问题。我试图加载大约 253k 个用户记录,每个记录都有一个唯一的 user_id。我的第一步是在 tje 标签上添加一个唯一约束,以确保用户只 运行 一次
CREATE CONSTRAINT ON (b:User) ASSERT b.user_id IS UNIQUE;
然后我尝试 运行 加载 CSV 并定期提交以提取此数据。
此查询失败,所以我尝试在设置前合并用户记录
USING PERIODIC COMMIT 1000
load csv with headers from "file:///home/data/uk_users.csv" as line
match (t:Territory{territory:"uk"})
merge (p:User {user_id:toInt(line.user_id)})-[:REGISTERED_TO]->(t)
set p.created=toInt(line.created), p.completed=toInt(line.completed);
修改定期提交值没有任何区别,返回相同的错误。
USING PERIODIC COMMIT 1000
load csv with headers from "file:///home/data/uk_buddies.csv" as line
match (t:Territory{territory:"uk"})
merge (p:User {user_id:toInt(line.user_id), created:toInt(line.created), completed:toInt(line.completed)})-[:REGISTERED_TO]->(t);
我收到以下错误:
LoadCsvStatusWrapCypherException: Node 9752 already exists with label Person and property "hpcm_uk_buddy_id"=[2446] (Failure when processing URL 'file:/home/data/uk_buddies.csv' on line 253316 (which is the last row in the file). Possibly the last row committed during import is line 253299. Note that this information might not be accurate.)
数字似乎大致吻合,CSV 文件总共包含 253315 条记录。 periodic commit好像也没有生效,节点数returns只有5446行
neo4j-sh (?)$ match (n) return count(n);
+----------+
| count(n) |
+----------+
| 5446 |
+----------+
1 row
768 ms
如果这个 ID 在 CSV 文件中只有大约 5000 行,我可以理解节点数不正确。但是我可以使用任何技术或命令来成功导入吗?
我认为您正在成为 MERGE
常见错误的牺牲品。相对于密码查询,说真的,这就像我关于密码常见问题的十大常见问题解答。看你在干嘛:
USING PERIODIC COMMIT 1000
load csv with headers from "file:///home/data/uk_buddies.csv" as line
match (t:Territory{territory:"uk"})
merge (p:User {user_id:toInt(line.user_id), created:toInt(line.created), completed:toInt(line.completed)})-[:REGISTERED_TO]->(t);
最后一次合并匹配整个关系的方式 merge works,而不仅仅是用户节点。因此,您可能正在创建不应该创建的重复用户。当您 运行 此合并时,即使具有这些确切属性的用户已经存在,与 t
节点的关系也不存在,因此它会尝试创建具有这些属性的新用户节点,以连接t
,这不是你想要的。
解决办法是先单独合并用户,再单独合并关系路径,像这样:
USING PERIODIC COMMIT 1000
load csv with headers from "file:///home/data/uk_buddies.csv" as line
match (t:Territory{territory:"uk"})
merge (p:User {user_id:toInt(line.user_id), created:toInt(line.created), completed:toInt(line.completed)})
merge (p)-[:REGISTERED_TO]->(t);
注意最后的两个合并。一个只创建用户。如果用户已经存在,它不会尝试创建副本,并且您应该可以接受您的约束(假设没有两个用户具有相同的 user_id,但创建的值不同)。仅合并用户后,再合并关系。
第二个查询的最终结果相同,但不应创建重复用户。