我有一个图表,其中节点可以是'资源'或者'外部依赖'。
资源(a.k.a。微服务)可能具有以下关系:
我目前正在使用以下查询搜索所有资源及其关系(进出):
Match (Resource)-[:CONNECTIONS*0..]-(ResourceDependency)-[:DEPENDS_ON*0..]-(ExternalDependency)
Where Resource.name =~ '.*service_name.*'
Return Resource, ResourceDependency, ExternalDependency
由于资源可以相互依赖,它们可能形成循环关系。当发生这种情况时,属于该圆圈的其中一个节点与" name"匹配。标准,查询永远不会完成,neo4j浏览器最终冻结。
如果我尝试将CONNECTIONS深度/ maxHops降低到8(* 0..8),它可以完美地工作。不幸的是,我已经拥有了比这更大的关系,所以这不是一个可行的解决方案(他们只是不会形成任何循环rel。)。
更新:
将maxHops设置为任何高于8的值会使Neo4j浏览器崩溃。
因为'资源'节点可以彼此具有N个深度关系(并最终形成循环引用),查询需要遍历所有图形,从而获得所有资源节点及其(一个深度)外部依赖关系的进出关系。
问题:
我怎样才能实现这一目标"其中"没有关于循环关系的表现问题的条款?
答案 0 :(得分:0)
下面的查询可能更适合您。如果没有,您可能想尝试在一个或多个可变长度路径上设置合理的上限。你可能比以前尝试的更高限制。
MATCH (resource:Resource)-[:CONNECTIONS*0..]->(resourceDependency)
WHERE resource.name =~ '.*service_name.*' AND (resourceDependency)-[:DEPENDS_ON]->()
WITH resourceDependency, COLLECT(resource) AS resources
MATCH (resourceDependency)-[:DEPENDS_ON*]->(externalDependency)
RETURN resourceDependency, resources, COLLECT(externalDependency) AS externalDependencies;
查询:
Resource
标签,并使用它。如果您未指定标签,则neo4j必须扫描数据库中的每个节点,以查看它是否具有:CONNECTIONS
或:DEPENDS_ON
关系。如果指定标签,neo4j只能扫描Resource
个节点。[:CONNECTIONS*0..]
获取所有依赖项,包括resource
本身。(resourceDependency)-[:DEPENDS_ON]->()
仅获取具有传出resourceDependency
关系的:DEPENDS_ON
个节点。resourceDependency
聚合所有依赖它的resources
。作为副作用,这确保了在此之后我们最终只有不同的resourceDependency
节点。我们以这种方式聚合是因为resourceDependency
可能依赖于大量资源,因此,在以下步骤中,我们希望确保我们尝试查找每个resourceDependency
的外部依赖项一旦 externalDependency
所依赖的所有resourceDependency
个节点。请注意,我们使用[:DEPENDS_ON*]
,相当于[:DEPENDS_ON*1..]
,因为我认为resourceDependency
不能也是externalDependency
。resourceDependency
,依赖于它的resource
个节点的集合,以及它所依赖的externalDependency
个节点的集合。答案 1 :(得分:0)
Cypher的可变长度模式匹配正在寻找与该模式匹配的所有可能路径,当您寻找不同的连接节点时,这并不是最有效的方法。
我们可以使用path expander procs in APOC Procedures来匹配不同的可达资源依赖项节点,然后从那里匹配到可能的外部依赖项。
MATCH (Resource) // you really should be using labels, WHERE CONTAINS, and indexes
WHERE Resource.name =~ '.*service_name.*'
CALL apoc.path.subgraphNodes(Resource, {relationshipFilter:'CONNECTIONS'}) YIELD node as ResourceDependency
MATCH (ResourceDependency)-[:DEPENDS_ON*0..1]->(ExternalDependency)
RETURN Resource, ResourceDependency, ExternalDependency
请注意,您将看到重复的数据,因为可以交换Resource和ResourceDependency的节点。如果您想减少这一点,可以在CALL之后添加以下内容:
...
WITH Resource, ResourceDependency
WHERE id(Resource) <= id(ResourceDependency)
...