So I think your issue here is that cypher batches up many updates into a single transaction and then commits them. How many it puts into a transaction is configurable with USING PERIODIC COMMIT
. I could be wrong, but I think normally it would treat the entire data load as a big transaction.
For you, this is problematic because when you're on, say, row #6, you might need to be referring back to a node that would have been created on row #3. Except that won't work; if the transaction hasn't committed yet because cypher is batching up a bunch of results) then the not-yet-committed result may not be available for a subsequent query running.
So you have a few options; one would be to do a two-pass IMPORT on that part file. On your first pass you might do this:
LOAD CSV WITH HEADERS FROM 'file:///path_to_file/part.csv' as csvLine FIELDTERMINATOR ' '
MERGE (p:Part {Name: csvLine.ID}) ON CREATE SET p.Size = csvLine.Size CREATE (o) -[:hasPart {Level: csvLine.Level}]-> (p) return count(*);
(This first one would assure all parts exist in the DB)
Then on the second pass you might do this:
LOAD CSV WITH HEADERS FROM 'file:///path_to_file/part.csv' as csvLine FIELDTERMINATOR ' ' MATCH (o:Part {Name: csvLine.ParentID}) MATCH (p:Part {Name: csvLine.ID}) CREATE (o) -[:hasPart {Level: csvLine.Level}]-> (p) return count(*);
(This would just link them with relationships)
Another option would be to do something like USING PERIODIC COMMIT 1
but I don't think that would be a good idea; there's transaction overhead, and that would drastically slow your data load if you have a fair amount of data.
EDIT If I were you, I'd do the two-pass import. Also, in general it's not a good idea to rely on record ordering in flat files like this, they tend to be messy. Finally, if you do two-pass import on your part file, note that you don't need your object file at all! Any object that's implicated will be created via the part file, and the object file doesn't add any extra properties than what part references.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…