Arangodb 以顶点为中心索引的奇怪行为

Arangodb 以顶点为中心索引的奇怪行为,arangodb,Arangodb,我在理解如何在ArangoDB中正确使用以顶点为中心的索引时遇到一些困难 在我的烹饪应用程序中,我有以下图表模式:recipe-[HasComponent]->配料 比如说,我想要所有需要少于0克胡萝卜的食谱。结果当然是空的 FOR recipe, constituent, p IN INBOUND 'ingredients/carrot' hasConstituent FILTER constituent.quantity.value < 0 RETURN recipe.

我在理解如何在ArangoDB中正确使用以顶点为中心的索引时遇到一些困难

在我的烹饪应用程序中,我有以下图表模式:recipe-[HasComponent]->配料

比如说,我想要所有需要少于0克胡萝卜的食谱。结果当然是空的

FOR recipe, constituent, p IN INBOUND 'ingredients/carrot' hasConstituent
    FILTER constituent.quantity.value < 0
    RETURN recipe._key
但在个人资料中:

Execution plan:
 Id   NodeType          Calls    Items   Runtime [s]   Comment
  1   SingletonNode         1        1       0.00000   * ROOT
  5   TraversalNode       433   432006       7.64893     - FOR recipe  /* vertex */, constituent  /* edge */ IN 1..1  /* min..maxPathDepth */ INBOUND 'ingredients/carrot' /* startnode */  hasConstituent
  6   CalculationNode     433   432006       0.28761       - LET #8 = (constituent.`quantity`.`value` < 0)   /* simple expression */
  7   FilterNode            1        0       0.08704       - FILTER #8
  8   CalculationNode       1        0       0.00000       - LET #10 = recipe.`_key`   /* attribute expression */
  9   ReturnNode            1        0       0.00001       - RETURN #10
非常欢迎任何帮助

用于遍历…中的顶点、边、路径,顶点或边上的过滤仅适用于结果,而不适用于实际访问的内容。至于这有什么意义,请记住,通常情况下,并非在遍历期间访问的所有顶点或边实际上都是结果的一部分:例如,如果in min..max参数中的min大于零-默认情况下为1-距离小于该值的顶点及其传入边不属于结果的一部分,但是我们必须去拜访

这就是为什么,如果要限制遍历期间访问的边,则必须在path变量上添加过滤器。例如:

FOR recipe, constituent, p IN INBOUND 'ingredients/carrot' hasConstituent
    FILTER p.edges[*].quantity.value ALL < 0
    RETURN recipe._key
这应该像您期望的那样使用索引。有关更多详细信息,请参阅和文档

我认为这回答了你问题的核心,现在来澄清你在途中发现的一些问题

我希望它按数字顺序对索引进行排序,然后 显著提高筛选或排序/限制请求的速度,但 现在,前一个请求需要~7.9秒。。。如果我使索引稀疏, 所需时间与无指数~3.9s时相同

这里有两件事

首先,听起来优化器更喜欢您的索引而不是边缘索引。这可能不应该是这样,因为没有我上面描述的更改,它并不比边缘索引更具体,只是稍微慢一点。您还没有指定您使用的ArangoDB版本,因此我无法具体评论。但是,如果您在撰写本文时正在使用受支持的次要版本(例如3.7.10或3.6.12)的最新修补程序版本,您可以将其报告为

其次,稀疏索引不会索引不存在的值或空值。因此,它不能用于可能报告空值的查询。现在请注意null<0为true,有关详细信息,请参阅文档中的。因此,您的查询component.quantity.value<0可能会报告空值,这就是为什么稀疏索引的处理方式不同,即根本无法使用

现在谈最后一点:

最难理解的部分是解释结果给出的执行计划与概要结果不同

explain输出显示一列Est.,这是该节点将发出/执行的行数/迭代数的估计值。相比之下,配置文件输出中的列项目是相应的精确数字。现在这个估计在某些情况下是好的,但在其他情况下是坏的。这不一定是个问题,如果不实际执行查询,它就不可能准确。如果由于估计使优化器为作业选择了错误的索引而导致出现问题,您可以使用。但事实并非如此

除此之外,您显示的两个平面似乎完全相同。

对于顶点、边、路径的遍历,对顶点或边的过滤只适用于结果,而不适用于实际访问的内容。至于这有什么意义,请记住,通常情况下,并非在遍历期间访问的所有顶点或边实际上都是结果的一部分:例如,如果in min..max参数中的min大于零-默认情况下为1-距离小于该值的顶点及其传入边不属于结果的一部分,但是我们必须去拜访

这就是为什么,如果要限制遍历期间访问的边,则必须在path变量上添加过滤器。例如:

FOR recipe, constituent, p IN INBOUND 'ingredients/carrot' hasConstituent
    FILTER p.edges[*].quantity.value ALL < 0
    RETURN recipe._key
这应该像您期望的那样使用索引。有关更多详细信息,请参阅和文档

我认为这回答了你问题的核心,现在来澄清你在途中发现的一些问题

我希望它按数字顺序对索引进行排序,然后 显著提高筛选或排序/限制请求的速度,但 现在,前一个请求需要~7.9秒。。。如果我使索引稀疏, 所需时间与无指数~3.9s时相同

这里有两件事

首先,听起来优化器更喜欢您的索引而不是边缘索引。这可能不应该是这样,因为没有我上面描述的更改,它并不比边缘索引更具体,只是稍微慢一点。您还没有指定您使用的ArangoDB版本,因此我无法具体评论。但是,如果您在撰写本文时正在使用受支持的次要版本(例如3.7.10或3.6.12)的最新修补程序版本,您可以将其报告为

其次,稀疏索引不会索引不存在的值或空值。因此,它不能用于可能报告空值的查询。现在请注意null<0为true,请参见文档中的 详细情况请参阅。因此,您的查询component.quantity.value<0可能会报告空值,这就是为什么稀疏索引的处理方式不同,即根本无法使用

现在谈最后一点:

最难理解的部分是解释结果给出的执行计划与概要结果不同

explain输出显示一列Est.,这是该节点将发出/执行的行数/迭代数的估计值。相比之下,配置文件输出中的列项目是相应的精确数字。现在这个估计在某些情况下是好的,但在其他情况下是坏的。这不一定是个问题,如果不实际执行查询,它就不可能准确。如果由于估计使优化器为作业选择了错误的索引而导致出现问题,您可以使用。但事实并非如此

除此之外,你展示的两个计划似乎完全相同

FOR recipe, constituent, p IN INBOUND 'ingredients/carrot' hasConstituent
    FILTER p.edges[*].quantity.value ALL < 0
    RETURN recipe._key