ArangoDB:GRAPH_EDGES命令在小集合上非常慢(超过20秒)

ArangoDB:GRAPH_EDGES命令在小集合上非常慢(超过20秒),arangodb,Arangodb,我正在评估ArangoDB,我发现GRAPH_边和GRAPH_顶点命令非常慢,在小集合上(300个顶点) 我有3个系列: 战术服务(300个顶点)->TuseCommand(300个边)->Tcommand(1个顶点) 使用图_边,此查询需要24秒 FOR service IN TactiveService LET usesCommand = ( return FIRST(GRAPH_EDGES("topvision", {}, { edgeExamples : [{_from

我正在评估ArangoDB,我发现GRAPH_边和GRAPH_顶点命令非常慢,在小集合上(300个顶点)

我有3个系列:

战术服务(300个顶点)->TuseCommand(300个边)->Tcommand(1个顶点)

使用图_边,此查询需要24秒

FOR service IN TactiveService
   LET usesCommand = (
      return FIRST(GRAPH_EDGES("topvision", {}, { edgeExamples : [{_from: service._id}], edgeCollectionRestriction : "TusesCommand", includeData:true, maxDepth : 1 }))
   )
   LET command = DOCUMENT(usesCommand[0]._to)
RETURN { service : service, usesCommand: usesCommand[0], command:command} 

对于相同的结果,此查询需要0.020秒

FOR service IN TactiveService
   LET usesCommand = (
      FOR usesCommand IN TusesCommand
         FILTER usesCommand._from == service._id
         RETURN usesCommand
   )
   LET command = DOCUMENT(usesCommand[0]._to)
RETURN { service : service, usesCommand: usesCommand[0], command:command} 
在for语句中,GRAPH_边对我来说是不可用的(GRAPH_顶点也有同样的问题)


关于这种缓慢的原因的想法是受欢迎的。

我们清楚地知道,
GRAPH\u EDGES
不适合像这样在查询中使用

因此,我们引入了一种新的方法,这种方法应该表现得更好

您可以这样表述您的查询,用遍历替换
图形\u边

FOR service IN TactiveService
LET usesCommand = (
                   FOR v, e IN 1..1 OUTBOUND service "TusesCommand"
                       FILTER e._from == service._id RETURN e
   )
   LET command = DOCUMENT(usesCommand[0]._to)
RETURN { service : service, usesCommand: usesCommand[0], command:command} 
请注意,指定的筛选器隐式地为
true
,因为我们查询了从
服务开始的
出站
边缘,因此
e.。\u from
始终等于
服务。\u id
。与指定
GRAPH“topvision”
和稍后限制遍历中要考虑的边集合不同,我们使用匿名图查询,只考虑边集合
tuseCommand

因此,将其简化一点,查询可以如下所示:

FOR service IN TactiveService
LET usesCommand = (
          FOR v, e IN 1..1 OUTBOUND service "TusesCommand" RETURN {v: v, e: e}
   )
RETURN { service : service, usesCommand: usesCommand} 
这可能会返回比查询更多的顶点,但只会获取一次;因此,结果集可能更大,但查询的删除
文档
调用减少了索引查找的数量

正如您在第二个查询中已经注意到并阐述的那样,如果您的实际问题在ArangoDB中工作得更好,您就可以自由选择这样处理您的数据


编辑:Michael肯定是对的,方向必须是
出站

我们很清楚
图边
不适合在查询中这样使用

因此,我们引入了一种新的方法,这种方法应该表现得更好

您可以这样表述您的查询,用遍历替换
图形\u边

FOR service IN TactiveService
LET usesCommand = (
                   FOR v, e IN 1..1 OUTBOUND service "TusesCommand"
                       FILTER e._from == service._id RETURN e
   )
   LET command = DOCUMENT(usesCommand[0]._to)
RETURN { service : service, usesCommand: usesCommand[0], command:command} 
请注意,指定的筛选器隐式地为
true
,因为我们查询了从
服务开始的
出站
边缘,因此
e.。\u from
始终等于
服务。\u id
。与指定
GRAPH“topvision”
和稍后限制遍历中要考虑的边集合不同,我们使用匿名图查询,只考虑边集合
tuseCommand

因此,将其简化一点,查询可以如下所示:

FOR service IN TactiveService
LET usesCommand = (
          FOR v, e IN 1..1 OUTBOUND service "TusesCommand" RETURN {v: v, e: e}
   )
RETURN { service : service, usesCommand: usesCommand} 
这可能会返回比查询更多的顶点,但只会获取一次;因此,结果集可能更大,但查询的删除
文档
调用减少了索引查找的数量

正如您在第二个查询中已经注意到并阐述的那样,如果您的实际问题在ArangoDB中工作得更好,您就可以自由选择这样处理您的数据


编辑:Michael肯定是对的,如果出于某种原因您不想像@dothebart建议的那样升级到2.8,那么方向必须是出站。您还可以修复旧的查询。 原件:

FOR service IN TactiveService
   LET usesCommand = (
      return FIRST(GRAPH_EDGES("topvision", {}, { edgeExamples : [{_from: service._id}], edgeCollectionRestriction : "TusesCommand", includeData:true, maxDepth : 1 }))
   )
   LET command = DOCUMENT(usesCommand[0]._to)
RETURN { service : service, usesCommand: usesCommand[0], command:command} 
查询的缓慢部分是寻找起点。GRAPH_Edge的API使用第二个参数作为开始示例<代码>{}
与所有起点匹配。因此,它现在首先计算所有顶点的所有出站边(这很昂贵,因为这实际上意味着对于开始集合中的每个顶点,我们收集开始集合中每个顶点的所有边)。然后,使用您给出的示例对所有找到的边进行后期筛选(这将再次删除几乎所有的边)。 如果用开始顶点的_id替换开始示例,它将只收集此特定顶点的边。 现在,您也只对一个方向(出站)的边感兴趣,因此您也可以在选项中给出它(因此,只有带有_from==service._id的边首先由图_边获取)


然而,我仍然希望@dothebart的版本在2.8中更快,我还建议切换到最新版本。

如果出于某种原因,您不想按照@dothebart的建议升级到2.8。您还可以修复旧的查询。 原件:

FOR service IN TactiveService
   LET usesCommand = (
      return FIRST(GRAPH_EDGES("topvision", {}, { edgeExamples : [{_from: service._id}], edgeCollectionRestriction : "TusesCommand", includeData:true, maxDepth : 1 }))
   )
   LET command = DOCUMENT(usesCommand[0]._to)
RETURN { service : service, usesCommand: usesCommand[0], command:command} 
查询的缓慢部分是寻找起点。GRAPH_Edge的API使用第二个参数作为开始示例<代码>{}
与所有起点匹配。因此,它现在首先计算所有顶点的所有出站边(这很昂贵,因为这实际上意味着对于开始集合中的每个顶点,我们收集开始集合中每个顶点的所有边)。然后,使用您给出的示例对所有找到的边进行后期筛选(这将再次删除几乎所有的边)。 如果用开始顶点的_id替换开始示例,它将只收集此特定顶点的边。 现在,您也只对一个方向(出站)的边感兴趣,因此您也可以在选项中给出它(因此,只有带有_from==service._id的边首先由图_边获取)


但是我仍然希望@dothebart的版本在2.8中更快,我也建议切换到最新版本。

谢谢,使用服务。_id作为起点而不是edgeExamples更快(5秒而不是20秒)。我使用2.8。谢谢,使用服务。_id作为起点而不是edgeExamples更快(5秒而不是20秒)。我使用2.8。谢谢,你的第二个查询是完美的,和加入一样快。谢谢,你的第二个查询是完美的,和加入一样快。