ArangoDB:数组元素中的性能指标

ArangoDB: performance index in array element

我在 ArangoDB 中有一个集合,其中填充了这样的元素:

{

  "id": "XXXXXXXX",
  "relation": [
    {
      "AAAAA": "AAAAA",
    },
    {
      "BBBB": "BBBBBB",
      "field": {
        "v1": 0,
        "v2": 0,
        "v3": 0
      }
    },
    {
      "CCCC": "CCCC",
      "field": {
        "v1": 0,
        "v2": 1,
        "v3": 2
      }
    },
  ]
}

我只想 return 具有 field.v1 > 0(或 v 值的组合)的元素。 我试过编写一个像这样的 AQL 查询,但它不使用索引,而且它有 200000 多个元素时速度太慢了。

FOR a in X
    FILTER LENGTH(a.relation) > 0
    LET relation =  a.relation
    FOR r in relation
        FILTER r.field > null 
        FILTER r.field.v1 > 0
return a

我已经尝试创建这些索引:

我能做什么?你能建议我对查询进行任何更改吗?

谢谢。

此致,

丹妮尔

全文索引目前只能用于 the FULLTEXT() function

目前无法使用索引来确定子对象的长度。一旦它们成为现实,这将是可以使用 function defined indices 解决的问题。

现在获得可用性能的唯一方法是在将文档写入集合时记住另一个属性的长度:

{
  "id": "XXXXXXXX",
  "length": 6,
  "relation": [
    {
      "AAAAA": "AAAAA",
    },
    {
      "BBBB": "BBBBBB",
      "field": {
        "v1": 0,
        "v2": 0,
        "v3": 0
      }
    },
    {
      "CCCC": "CCCC",
      "field": {
        "v1": 0,
        "v2": 1,
        "v3": 2
      }
    },
  ]
}

<小夹子>you look like you want to be using graph features for your data layout?

我建议进行以下更改,但它们不会显着加快查询速度:

  • 过滤器 FILTER r.field > nullFILTER r.field.v1 > 0 是多余的。你可以只使用后者 FILTER r.field.v1 > 0 并省略其他过滤条件

  • 辅助变量LET relation = a.relation定义在a.relation用于LENGTH(a.relation)计算之后。如果在 LENGTH() 计算之前定义辅助变量,则可以像这样在其中使用它:LET relation = a.relation FILTER LENGTH(relation) > 0。这将节省一些处理时间

  • 原始查询检查每个 v1 值,如果文档中的多个 v1 值满足过滤条件,则可能 return 每个文档多次。这意味着原始查询可能 return 比集合中实际存在的文档更多。如果不需要,我建议使用子查询(见下文)

将上述修改应用于原始查询时,这就是我想出的:

FOR a IN X 
  LET relation = a.relation
  FILTER LENGTH(relation) > 0 
  LET s = (
    FOR r IN relation
      FILTER r.field.v1 > 0 
      LIMIT 1 
      RETURN 1
  )
  FILTER LENGTH(s) > 0 
  RETURN a

正如我所说,这可能不会显着提高性能,但是,您可能会从查询中得到不同的(可能是期望的)结果,即如果文档中的多个 v1 满足过滤器,则文档较少条件。

关于索引:全文索引和散列索引在这里无济于事,因为它们仅支持相等比较,但查询的过滤条件大于。一般来说,唯一可能对这里有益的索引类型是跳表索引。但是,2.7 中根本不支持索引数组值,因此索引 relation[*].field 无济于事,仍然不会像您报告的那样使用索引。

ArangoDB 2.8 将是第一个支持索引单个数组值的版本,您可以在 relation[*].field.v1 上创建索引。

2.8 中的查询仍然不会使用该索引,因为数组索引仅用于 IN 比较运算符。它们不能与查询中的 > 一起使用。此外,当将过滤条件写为 FILTER r[*].field.v1 > 0 时,对于上面的示例文档,这将计算为 FILTER [null, 0, 0] > 0,这将不会产生所需的结果。

这里可以提供一个比较运算符修饰符(暂定名称),它可以告诉运算符 <<=>>===!= 到 运行 对其左操作数的所有成员进行比较。可以有ALLANY修改,这样过滤条件就可以写成FILTER a.relation[*].field.v1 ANY > 0。但请注意,这还不是一个现有的功能,而只是我关于未来如何解决这个问题的快速草稿。