我有一个图数据集,其中包含大量相对较小的不相交图。我需要从一组符合特定搜索条件的顶点中找到所有可达的顶点。我使用以下查询:
FOR startnode IN nodes
FILTER startnode._key IN [...set of values...]
FOR node IN 0..100000 OUTBOUND startnode edges
COLLECT k = node._key
RETURN k
即使返回正确的结果,查询也非常慢。这是因为Arango实际上多次遍历相同的子图。例如,假设有以下子图:
a -> b -> c -> d -> e
当过滤条件选择了顶点a和c时,Arango会从a和c开始进行两次独立的遍历。在这两次遍历中,它都会访问顶点d和e,这会浪费时间。添加uniqueVertices选项也没有帮助,因为在不同的遍历中不会检查顶点的唯一性。
为了确认对性能的影响,我创建了一个额外的根文档,并添加了从它到过滤器找到的所有文档的链接:
FOR startnode IN nodes
FILTER startnode._key IN [...set of values...]
INSERT { _from: 'fakeVertices/0', _to: startnode._id } IN fakeEdges
现在,以下查询的运行速度比原始查询快4倍,但生成的结果相同:
FOR node IN 1..1000000 OUTBOUND 'fakeVertices/0' edges, fakeEdges
OPTIONS { uniqueVertices: 'global', bfs: true }
COLLECT k = node._key
RETURN k
不幸的是,我不能为我的所有查询创建假顶点/边,因为创建它需要更多的时间。
我的问题是:Arango是否提供了一种方法来确保在给定的查询中所有遍历中所访问的顶点的唯一性?2如果没有,是否有更好的方法来解决上述问题?
1条答案
按热度按时间taor4pac1#
据我所知,这就是
uniqueVertices
选项的作用,但是对于FOR ...
语句的每次迭代,它认为从***那个***起始节点开始遍历的顶点是唯一的。它不知道在FOR ...
语句中其他节点上发生的其他遍历。看起来每次都要遍历大量的顶点,并且这从每个新的开始节点发生。只是把它扔到墙上看看它是否能坚持下去,但是把这两个查询组合起来,把
OPTIONS
加到原始查询上怎么样?另外,我强烈推荐使用命名图,而不是指定边集合。它不仅更加灵活,还允许使用最短路径计算,这可能会有所帮助。