我尝试使用cypher命令行从cvs文件中将数据模式加载到neo4j中。我有两个数据文件,一个包含对象,另一个包含对象部分。
目标文件:
ID
ABC-DE
DEF
部分档案:
ID ParentID Level Size
ABC ABC-DE 1 3
DE ABC-DE 1 2
AB ABC 2 2
BC ABC 2 2
DE DEF 1 2
F DEF 2 1
A AB 3 1
B AB 3 1
B BC 3 1
C BC 3 1
D DE 3 1
E DE 3 1
用于加载数据的Cypher命令行:
LOAD CSV WITH HEADERS FROM 'file:///path_to_file/object.csv' as csvLine FIELDTERMINATOR '\t' CREATE (:Object { Name: csvLine.ID}) RETURN count(*);
LOAD CSV WITH HEADERS FROM 'file:///path_to_file/part.csv' as csvLine FIELDTERMINATOR '\t' MATCH (o:Object {Name: csvLine.ParentID}) MERGE (p:Part {Name: csvLine.ID}) ON CREATE SET p.Size = csvLine.Size CREATE (o) -[:hasPart {Level: csvLine.Level}]-> (p) RETURN count(*);
LOAD CSV WITH HEADERS FROM 'file:///path_to_file/part.csv' as csvLine FIELDTERMINATOR '\t' MATCH (o:Part {Name: csvLine.ParentID}) MERGE (p:Part {Name: csvLine.ID}) ON CREATE SET p.Size = csvLine.Size CREATE (o) -[:hasPart {Level: csvLine.Level}]-> (p) return count(*);
前两个命令行正确执行,分别创建2个和3个节点以及相应的链接。第三个命令行只创建4个节点:AB,BC,D和E.显然,只创建和链接链接到现有节点的节点。
从CSV文件内容中,我们可以看到父节点在子节点之前列出,因此我们可以预期节点A,B和C可以创建并相应地链接到AB和BC。
CSV的当前行为是否加载了预期的行为,这会阻止加载此类模式,或者我的代码或错误中是否存在问题?
neo4j 2.1.7和neo4j 2.2.0-M04都存在此问题。
答案 0 :(得分:1)
所以我认为你的问题是cypher将许多更新批量编译到一个事务中,然后提交它们。它投入交易的数量是configurable with USING PERIODIC COMMIT
。我可能是错的,但我认为通常它会把整个数据加载视为一个大事务。
对于你来说,这是有问题的,因为当你进入第6行时,你可能需要引用一个本来应该在第3行创建的节点。除了不工作;如果事务尚未提交,因为cypher正在对一堆结果进行批处理)那么尚未提交的结果可能无法用于后续运行的查询。
所以你有几个选择;一个是在该部分文件上进行两次导入IMPORT。在你第一次通过时你可以这样做:
LOAD CSV WITH HEADERS FROM 'file:///path_to_file/part.csv' as csvLine FIELDTERMINATOR '\t'
MERGE (p:Part {Name: csvLine.ID}) ON CREATE SET p.Size = csvLine.Size CREATE (o) -[:hasPart {Level: csvLine.Level}]-> (p) return count(*);
(第一个将确保DB中存在所有部分)
然后在第二遍你可能会这样做:
LOAD CSV WITH HEADERS FROM 'file:///path_to_file/part.csv' as csvLine FIELDTERMINATOR '\t' MATCH (o:Part {Name: csvLine.ParentID}) MATCH (p:Part {Name: csvLine.ID}) CREATE (o) -[:hasPart {Level: csvLine.Level}]-> (p) return count(*);
(这只会将它们与人际关系联系起来)
另一种选择是做USING PERIODIC COMMIT 1
之类的事情,但我认为这不是一个好主意;存在交易开销,如果您有相当数量的数据,这将大大减慢您的数据负载。
编辑如果我是你,我会进行双程导入。此外,一般来说,依靠像这样的平面文件中的记录排序并不是一个好主意,它们往往是凌乱的。最后,如果您对零件文件进行双程导入,请注意您根本不需要您的目标文件!任何涉及的对象都将通过零件文件创建,并且对象文件不会添加任何额外的属性而不是部件引用。