【问题标题】:Filtering Arango query results to report an array intersection in AQL过滤 Arango 查询结果以报告 AQL 中的数组交集
【发布时间】:2020-01-21 16:56:41
【问题描述】:

我正在尝试使用 ArangoDB 作为我目前使用的 Postgres 的替代品。在 Postgres 中,我有一个表格,zuffs 包含具有以下形式的行

 hash       passes     visits   

 123        {1,2,4}   {2,3,4,5}

passesvisits 都是 int[]。为了建立passes和访问的交集`我会写

SELECT ARRAY
(
 SELECT UNNEST(a1) INTERSECT SELECT UNNEST(a2))
 FROM (SELECT passes AS a1,visits as a2 FROM zuffs where hash = 1) q;

Postgres 强制执行以返回结果{2,4}

现在假设我在 ArangoDB 中有集合 zuffs 和以下 documents

{"hash":45,"passes":[1,2,3],"visits":[3,11,17]}

{"hash":76,"passes":[11,2],"visits":[3,4,17]}

{"hash":13,"passes":[11,21],"visits":[13,44,27]}

{"hash":7,"passes":[2],"visits":[4,67]}

我不清楚我将如何执行以下操作

  1. 为带有hash 45的文档建立passesvisits的交集I1
  2. 获取该结果并返回同一集合中与上面获得的交集 I2 具有非空交集的其他文档的哈希值。

虽然我很喜欢 ArangoDB,但遗憾的是它有自己的查询语言,而不仅仅是使用所需的 SQL 超集。在这种情况下,我发现我必须以某种方式使用FOR INFILTER,但我完全不清楚如何使用。

【问题讨论】:

    标签: json filter arangodb


    【解决方案1】:

    作为一名 SQL 专家,我还与 AQL 的语法差异作斗争。然而,它真的并没有那么难理解,这使得“学习”只是时间和使用的函数。

    我确信还有其他方法可以做到这一点,但这里有一个快速/肮脏的例子:

    1. 找到你要匹配的文档,得到它的交集
    2. 对于zuffs 中的每个文档z,计算交集并查找匹配项
    3. 返回匹配文档的hash
    LET match = (
        FOR z IN zuffs
            FILTER z.hash == 45
            FOR i IN INTERSECTION(z.passes, z.visits)
                RETURN i
    )
    FOR z IN zuffs
        LET i = INTERSECTION(z.passes, z.visits)
        FOR m IN match
            FILTER m IN i
                RETURN z.hash
    

    返回:

    [
      45
    ]
    

    给定您的示例数据集,您只能返回一份满足要求的文档 (45)。添加更多文档或修改其他文档之一以具有公共交集将提供更有趣的结果。

    注意事项:

    1. 从 SQL 迁移到 AQL 会让您的思维从“集合”(行)转向“循环”(事物)。
    2. 跟踪返回(或本机)类型(数组与对象/字符串/等),并相应地处理每条数据(注意match 中的FOR i IN INTERSECTION...)。
    3. 使用ExplainProfile 按钮(或功能)查看查询的执行情况。想想其他可以实现结果的方法,并尝试让它更快!

    例如:

    LET match = FIRST(
        FOR z IN zuffs
            FILTER z.hash == 45
            RETURN INTERSECTION(z.passes, z.visits)
    )
    FOR z IN zuffs
        FILTER LENGTH( INTERSECTION(match, INTERSECTION(z.passes, z.visits)) ) > 0
            RETURN z.hash
    

    两个示例的 match 部分返回相同的结果(具有单个值 3 的数组),但它们以不同的方式执行此操作。而不是做FOR m IN match...,我可以使用带有过滤器的本机数组函数。实际上,第一个例子比第二个例子快得多,原因在“解释”计划中很明显。

    我发现它非常有助于熟悉 high levelfunction 文档。这两个地方几乎可以满足您使用 AQL 取得成功所需的一切(除了查询调优、索引等“全局”的东西)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-04-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-02
      • 1970-01-01
      • 2019-08-24
      相关资源
      最近更新 更多