Cypher查询优化咨询:规避MATCH语句及子图关系过滤实现
Cypher查询优化方案
原始查询
match (node{property}) apoc.call.subgraphnodes( rel filter (has_X,is_y), label filter (+x|/y|>z)) match (z)-[is_y]-(y) return collect(z.id)
问题1:能否避免使用MATCH语句以减少数据库访问?
完全可以。你可以直接借助apoc.subgraph.all(替代apoc.call.subgraphnodes)一次性获取子图的节点和关系,从返回结果中直接提取目标节点,无需额外执行MATCH语句。
示例优化查询:
MATCH (node {property}) CALL apoc.subgraph.all(node, { relationshipFilter: 'has_X|is_y', labelFilter: '+x|/y|>z' }) YIELD nodes, relationships UNWIND relationships AS rel WHERE TYPE(rel) = 'is_y' // 提取与起始节点关联的节点,去重后收集ID WITH COLLECT(DISTINCT CASE WHEN STARTNODE(rel) = node THEN ENDNODE(rel) ELSE STARTNODE(rel) END ) AS connectedNodes RETURN [n IN connectedNodes | n.id] AS nodeIds
这个查询直接从子图返回的关系中筛选目标类型,提取关联节点,避免了二次MATCH带来的额外数据库访问。
问题2:能否用subgraphAll返回关系并按TYPE过滤?
可以。apoc.subgraph.all会返回子图包含的所有nodes和relationships,你可以在返回结果后对关系进行过滤,也可以在调用时直接通过relationshipFilter指定仅包含目标类型的关系,后者效率更高。
方式一:返回后过滤
如问题1中的示例,通过UNWIND relationships AS rel展开关系,再用WHERE TYPE(rel) = 'is_y'筛选。方式二:调用时直接过滤
如果只需要is_y类型的关系,可以在调用apoc.subgraph.all时直接限定关系类型,减少子图生成的数据量:
MATCH (node {property}) CALL apoc.subgraph.all(node, { relationshipFilter: 'is_y', labelFilter: '+x|/y|>z' }) YIELD nodes, relationships UNWIND relationships AS rel WITH COLLECT(DISTINCT CASE WHEN STARTNODE(rel) = node THEN ENDNODE(rel) ELSE STARTNODE(rel) END ) AS connectedNodes RETURN [n IN connectedNodes | n.id] AS nodeIds
内容的提问来源于stack exchange,提问作者ameya gupta
相关产品推荐
相关产品推荐

