命名图遍历中使用的极限边

时间:2018-10-10 18:10:09

标签: arangodb aql

Q:我可以限制遍历命名图AQL时系统将尝试使用的边集吗?

场景:

如果我有一个具有两个顶点集合和两个边缘集合的命名图productGraph:

  • 顶点:产品,价格
  • prodParentOf(产品A是产品B的父级)
  • prodHasPrice(产品A的价格为$ X)

如果现在我想要产品A的产品子级(且没有价格),我想做这样的事情

WITH product
FOR v, e, p IN OUTBOUND 'product/A'
GRAPH 'productGraph'
RETURN {vertice:v, edge:e, path: p}

但是,如果我看一下解释计划,就会发现系统尝试对prodParentOf和prodHasPrice都使用索引(即使我将product集合明确地放在了With子句中):

Indexes used:
 By   Type   Collection     Unique   Sparse   Selectivity   Fields               Ranges
  2   edge   prodHasPrice   false    false        75.00 %   [ `_from`, `_to` ]   base OUTBOUND
  2   edge   prodParentOf   false    false        65.37 %   [ `_from`, `_to` ]   base OUTBOUND

我可以限制查询命名图时系统将尝试使用的边集吗?还是我必须在查询中使用边缘集合。 (在我看来,这通常比遍历边缘集合比命名图更好)。

这里是使用边集合的同一查询

FOR v, e, p IN OUTBOUND 'product/A'
prodParentOf
RETURN {vertice:v, edge:e, path: p}

1 个答案:

答案 0 :(得分:0)

WITH clause并未对属于哪些集合施加限制 您命名的图表中的将会用于遍历。主要用于集群中的遍历,以声明将涉及哪些集合。这有助于避免死锁,如果在查询运行时延迟锁定集合,可能会发生死锁。

如果使用单个服务器实例,则WTIH子句是可选的。它对结果没有影响。如果要从遍历中排除集合,则可以使用集合集而不是命名图,也可以将FILTERIS_SAME_COLLECTION()一起使用。使用集合集会更有效,因为使用更少的边缘集合时,需要遍历的边缘会更少,而在大多数情况下,遍历之后会应用滤镜。

FOR v, e, p IN 1..5 OUTBOUND 'verts/start' GRAPH 'named-graph'
  FILTER (FOR id IN p.edges[*]._id RETURN IS_SAME_COLLECTION('edgesX', id)) ALL == true
  RETURN p

如果遍历的深度仅为1,则过滤器查询会更简单:

FOR v, e, p IN INBOUND 'product/A' GRAPH 'productGraph'
  FILTER IS_SAME_COLLECTION('prodParentOf', e)
  RETURN {vertex: v, edge: e, path: p}

将来可能会出现修剪路径的方法,这也将有助于命名图方案。