ArangoDB 过滤Arango查询结果以报告AQL中的数组交集

monwx1rj  于 2022-12-09  发布在  Go
关注(0)|答案(1)|浏览(149)

我正在尝试用ArangoDB来替代我目前使用的Postgres。

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
{“哈希”:45,“通过”:[1,2,3],“访问”:[3,11,17]}
{“哈希”:76,“通过”:[11,2],“访问”:[3,4,17]}
{“哈希”:13,“通过”:[11,21],“访问”:[13,44,27]}
{“哈希”:7,“通过”:[2],“访问”:[4,67]}
我不清楚如何执行以下操作
1.为带有hash 45的文档建立passesvisits的交集I1
1.获取该结果并返回同一集合中与上面获得的交集I2具有非空交集的其他文档的哈希。
虽然ArangoDB有很多我喜欢的地方,但我发现它有自己的查询语言,而不是只使用SQL的超集。在这个例子中,我已经知道我将不得不在某种程度上使用FOR IN沿着FILTER,但我一点也不清楚如何使用。

z0qdvdin

z0qdvdin1#

作为一名SQLMaven,我也与AQL的语法差异作过斗争。然而,它最终并没有那么难理解,这使得“学习”只是时间和使用的函数。
我相信还有其他方法可以做到这一点,但这里有一个快速/肮脏的例子:
1.找到要匹配的文档,并获取其交集积
1.对于zuffs中的每个文档z,计算交集并查找匹配项
1.返回匹配文档的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会使您的思维从“集合”(行)转变为“循环”(对事物)。
1.跟踪返回(或本机)类型(数组与对象/字符串等),并相应地处理每一段数据(注意match中的FOR i IN INTERSECTION...)。
1.使用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所需的一切(除了查询调优、索引等“全局”内容)。

相关问题