我尝试使用py2neo模块来执行以下操作,以获取neo4j数据库中大量节点的信息,这些节点的id已经知道:
query = f'''
MATCH
(n:MY_LABEL)
OPTIONAL MATCH
(n) -- (u:OTHER_LABEL) // Won't always have a neighbor
WHERE
id(n) in [{','.join(very_long_list_of_nids)}]
RETURN
id(n) as nid,
n.feature1,
u.feature2
'''
resp = graph.run(query)
字符串
我注意到,省略WHERE
子句,并在返回每个n:MY_LABEL
节点的内容后进行过滤要快得多。有没有更优雅的方式来做到这一点?
作为参考,very_long_list_of_nodes
列表大约有500k个元素长(我曾尝试将其批处理成更小的10k块,也遇到了同样的问题),数据库包含4m个节点和10m条边。
1条答案
按热度按时间db2dz4w81#
您应该:
1.将
WHERE
子句移到MATCH
子句的正下方。目前,您的WHERE
子句位于OPTIONAL MATCH
子句下,因此只有找到所有MY_LABEL
节点的关系后才能进行ID过滤。1.从
MATCH
子句中删除:MY_LABEL
限定。如果已经通过native ID获取节点,则不需要检查标签;而且你没有使用索引。1.将ID列表作为parameter传递。这将使Cypher查询规划器运行得更快(因为Cypher代码很简单),一旦创建了计划,它将被缓存并在每次使用新的ID列表重新运行查询时重用。这也使您的客户端代码更简单,更快。
这应该更快:
字符串
此外,如果
MY_LABEL
和OTHER_LABEL
之间的关系总是单向流动,则应考虑在OPTIONAL MATCH
子句中使用定向关系模式(-->
或<--
),特别是当MY_LABEL
节点具有其他类型的反向流动关系时。