首页 文章

ArangoDB:数组元素中的性能索引

提问于
浏览
2

我在ArangoDB中有一个集合,其中包含以下元素:

{

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

我想只返回具有 field.v1 > 0 (或v值的组合)的元素 . 我've tried to write an AQL query like this one, but it doesn' t使用索引,它有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

我试过创建这些索引:

  • full text on relation[*]field

  • skip list on relation[*]field

  • hash on relation[*]field 但没有结果 .

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

谢谢 .

最好的祝福,

丹尼尔

2 回答

  • 1

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

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

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

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

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

    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 满足过滤条件,则会减少文档 .

    关于索引:全文和哈希索引在这里没有帮助,因为它们仅支持相等比较,但查询的过滤条件大于 . 这里唯一可能有益的索引类型是skiplist索引 . 但是,2.7中根本不支持索引数组值,因此索引 relation[*].field 将无济于事,并且仍然不会像您报告的那样使用索引 .

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

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

    这里可以帮助的是比较运算符修饰符(工作 Headers ),它可以告诉运算符 <<=>>===!= 在其左操作数的所有成员上运行比较 . 可能会有 ALLANY 修改,因此过滤条件可以简写为 FILTER a.relation[*].field.v1 ANY > 0 . 但是请注意,这还不是现有的功能,而只是我的快速草案,说明将来如何解决这个问题 .

  • 0

    全文indes当前只能与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
          }
        },
      ]
    }
    

    <Clippy> you look like you want to be using graph features for your data layout? </ Clippy>

相关问题