首页 > 解决方案 > 将 tsv 文件中的选定行导入 neo4j

问题描述

我有一个具有这种格式关系的文件:

!comment
!comment
nodeID   nodeName   edgeType   nodeID
nodeID   nodeName   edgeType   nodeID
nodeID   nodeName   edgeType   nodeID

我想将该文件的节点和边缘导入到我的 neo4j 数据库中。
我尝试了以下步骤:

  1. 在节点 ID 上创建唯一约束
  2. 读取文件,跳过注释行,从每一行创建唯一节点(如果节点已经存在,则跳过行)
  3. 读取文件,跳过注释行,从每一行创建边缘
// Each node id is unique
CREATE CONSTRAINT ON (n:Node) ASSERT n.id IS UNIQUE

// For each row not starting by "!", create node if it doesn't exist
LOAD CSV FROM "file:///relationships.tsv" AS row
FIELDTERMINATOR '\t'
WITH row
WHERE NOT row =~ '^!.*'
CREATE (:Node {id: row[0], name: row[1]})

// For each row not starting by "!", create edge
LOAD CSV FROM "file:///relationships.tsv" AS row
FIELDTERMINATOR '\t'
WITH row
WHERE NOT row =~ '^!.*'
MATCH (n:Node), (m:Node)
WHERE n.id = row[0] AND m.id = row[3]
WITH n, m, row
CASE row[2]
  WHEN 'F' THEN
    CREATE UNIQUE (m)-[:Edge {type: 'friend'}]->(n)
  WHEN 'P' THEN
    CREATE UNIQUE (m)-[:Edge {type: 'partner'}]->(n)
END

上面的代码不起作用。作为密码新手,我不确定自己做错了什么。我希望最终合并步骤 2 和 3 以读取文件一次并完成它。如何有效地导入这些数据?

标签: neo4jcypher

解决方案


[更新两次]

此版本的第三个查询应该可以工作:

LOAD CSV FROM "file:///relationships.tsv" AS row
FIELDTERMINATOR '\t'
WITH row
WHERE NOT row[0] STARTS WITH '!'
MATCH (m:Node)
WHERE m.id = row[3]
MERGE (n:Node {id: row[0]})
SET n.name = row[1]
FOREACH (domain IN
    CASE
        WHEN row[2] = 'F' THEN ['friend']
        WHEN row[2] = 'P' THEN ['partner']
        ELSE []
    END |
    MERGE (t)-[:Edge {type: domain}]->(p)
);

它正确地测试了行中的第一项(不是整个行列表——它不是字符串)的起始“!”。它还使用一个FOREACH子句来执行条件更新(CypherCASE子句本身不支持)。此查询还使用MERGE不推荐使用的CREATE UNIQUE. 它还使用MERGE而不是CREATE创建n节点,以确保您不会产生重复项(例如,如果您重新运行相同的查询)。


推荐阅读