获取没有某种关系的节点 (Cypher/Neo4j)

9

我有以下两种节点类型:

c:City {name: 'blah'}
s:Course {title: 'whatever', city: 'New York'}

希望创建这个:

(s)-[:offered_in]->(c)

我正在尝试获取所有未与城市关联的课程,并将其与城市建立关系(如果不存在,则创建城市)。然而,我的数据集包含约500万个节点,任何查询都会超时(除非我每次以10k的增量进行查询)。
... 有人有什么建议吗?
编辑:
这是我现在运行的作业查询(必须按照10k的块(数百万)进行操作,因为它已经需要几分钟。如果不存在,则创建城市)。
match (j:Job)
where not has(j.merged) and has(j.city)
WITH j 
LIMIT 10000
MERGE (c:City {name: j.city})
WITH j, c
MERGE (j)-[:in]->(c)
SET j.merged = 1
return count(j)

目前还没有一个好的方法来过滤掉已经匹配的内容,所以尝试通过给其打上自定义的“merged”属性进行标记,而我已经在此属性上建立了索引。


你能分享一下你目前在尝试什么吗? - JohnMark13
我认为没有更多的上下文是无法回答这个问题的(假设job == course,in == offered_in)。你是在现有数据上操作,还是批量导入?您能告诉我们一些关于您的系统设置的信息吗?您可以使用WHERE NOT (j)-[:in]->(),而不是“merged”。 - JohnMark13
你是否通过浏览器界面看到了超时? - Jim Biard
1个回答

4

500000个节点是相当多的,而且在你的另一个问题中,你提到有90%的节点没有你想要创建的关系,所以这需要一些时间。如果没有更多了解你的系统(规格、neo设置、编程环境)和你何时运行它(在旧数据上还是在插入时),那么以下是一个较为整洁的解决方案的最佳猜测:

MATCH (j:Job)
WHERE NOT (j)-[:IN]->() AND HAS(j.city)
MERGE (c:City {name: j.city})
MERGE (j)-[:IN]->(c)
return count(j)

显然,您可以根据需要重新添加您的限制。

这是5,000,000个节点。由于某种原因,我之前的查询(以及这个)会产生大量重复的城市...我已经放弃了,只好编写一个Python脚本来手动分批处理。虽然需要很长时间,但似乎保持了唯一性并且达到了我的需求。另外,我也尝试过使用"CREATE UNIQUE"(因为它应该保证每个部分的唯一性),但它一直告诉我要么是"未绑定模式",要么不能这样使用(或类似的错误),所以我从未让它起作用。 - Diaspar
1
你定义了哪些索引,并且是否使用了上述的两个合并语句?单个合并(MERGE (j)-[:IN]->(c:City {name: j.city}))会因为未匹配的未绑定模式而产生重复。你能否更新你的问题,提供更多信息(你尝试了什么,以及失败了什么),因为这应该是完全可能的! - JohnMark13

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接