LOAD CSV和Commits:条件(FOREACH / CASE)执行行为奇怪

时间:2017-07-04 01:13:27

标签: neo4j cypher graph-databases

我正在使用Neo4j 3.1版,运行我认为非常简单的导入,但遇到了非常严重的问题。我导入有关酒吧的数据(对于非英国用户,公共场所 - 您有品脱和放松的地方!)。 (pl:PubListing)(u:BiteUser)进行了评论,创建了(bc:BiteComment)。我有两个CSV文件,并且已经导入了(pl:PubListing)个节点,因此我尝试导入链接到每个发布的评论(pl.source_pub_id)和每个用户({{1} }})。重要的是,我想将它们作为一种简单的关系加入,并且为了得到一个更好的词语 - 我称之为链条。

通过这种方式,用户发布的最后两条评论(u.username是最新评论,而bc1是最新评论但是一条评论)与用户相关联:

第一条评论:

bc2

和第二个:

(u:BiteUser)-[:USER_PREVIOUS_COMMENT]->(bc1), (u)-[:USER_MADE_COMMENT]->(bc1)

到目前为止,非常正常(网络应用中的面包和黄油,注释可能类似于登录事件,密码更改,帖子等)。但是,这并不是在一个简洁的事务中发生,而是在通过CSV加载时。我的查询如下。

N.B。 - 预处理脚本对数据进行排序,以便所有注释按时间顺序排列:最早的注释首先出现,因此没有逻辑将注释放在链中的正确位置。

N.B。 II - 我在这里的几个地方使用(u)-[:USER_MADE_COMMENT]->(bc2), (bc1)-[:USER_PREVIOUS_COMMENT]->(bc2)而不是创建,因为期望在新数据可用时或在此项目后续跟踪时,查询可能会多次运行(它是' sa谈话)尝试在技术困难后重新导入数据。它不是任何想象力的生产脚本,这里的查询优化不是我的优先事项列表中的首要任务。

MERGE

问题在于,目前它为每个评论创建了两种关系。但是,我在更改查询的开头并在LOAD CSV WITH HEADERS FROM 'file:///output-comments-0031.csv' AS line // find the pub it refers to MATCH (pl:PubListing) WHERE pl.source_pub_id = toInteger(line.source_pub_id) MERGE (u:BiteUser {username: line.username }) // ensure the comment node is created MERGE (bc:BiteComment { source_comment_id: toInteger(line.source_comment_id) }) SET // be flexible on scraped input bc += line, // indices should be integers, though bc.source_pub_id = toInteger(line.source_pub_id), bc.source_comment_id = toInteger(line.source_comment_id), bc.created_timestamp = toInteger(line.created_timestamp) // link the comment to the user and pub directly MERGE (u)-[:USER_MADE_COMMENT]->(bc) MERGE (bc)-[:COMMENT_ABOUT_PUT]->(pl) // and in a chain // - this section will be repeated to link the comment to the // pub, in a chain. I've only included the user example // to isolate the problem for SO WITH u, pl, bc OPTIONAL MATCH (u)-[r:USER_PREVIOUS_COMMENT]->(lc:BiteComment) WHERE lc <> bc WITH u, bc, pl, r, CASE WHEN r IS NULL THEN [] ELSE [1] END AS upc, lc FOREACH (i IN upc | DELETE r CREATE (bc)-[:USER_PREVIOUS_COMMENT]->(lc) ) // pre-processing means we know this is the most recent comment // that the graph has seen yet MERGE (u)-[:USER_PREVIOUS_COMMENT]->(bc) 行之后添加以下行时,因此每个事务加载一个注释,它按预期工作。

LOAD CSV

然后,

WITH line SKIP 0 LIMIT 1

然后......

WITH line SKIP 1 LIMIT 1

......你明白了。

我的问题是这个。 为什么在CSV导入期间会发生这种情况,如何在不将导入作为单个事务运行的情况下停止?

1 个答案:

答案 0 :(得分:2)

记住Cypher查询不会每行迭代处理是很重要的。相反,它们同时处理所有行,迭代是对所有行进行的每次操作。

所以你先对所有行进行MATCH,然后对所有行进行MERGE(LOAD CSV之后的第二次操作)等。

您的CSV导入似乎偏离了(错误的)假设迭代处理行,因此您对先前处理的行有某种依赖性,这将无效。

我建议您修复CSV以删除对上一行处理的依赖性。

要么你需要做一个评论的COLLECT(),然后取最后两个条目(比如WITH collectedComments[-2..] as lastTwo,然后别名每个节点并创建相关的关系),或者你&#39;我需要添加时间戳或其他一些排序方法,然后执行导入后查询以获取最新的两条评论并对其进行排序。