过滤 Arango 查询结果以报告 AQL 中的数组交集
Filtering Arango query results to report an array intersection in AQL
我正在尝试使用 ArangoDB 来替代我目前使用的 Postgres。在 Postgres 中,我有一个 table、zuffs
包含具有以下形式的行
hash passes visits
123 {1,2,4} {2,3,4,5}
其中 passes
和 visits
都是 int[]
。为了建立 passes
和 visits 的交集,我会写
SELECT ARRAY
(
SELECT UNNEST(a1) INTERSECT SELECT UNNEST(a2))
FROM (SELECT passes AS a1,visits as a2 FROM zuffs where hash = 1) q;
Postgres 主动执行 return 结果 {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]}
我不清楚我将如何执行以下操作
- 为带有
hash
45. 的文档建立 passes
和 visits
的交集 I1
- 取该结果和return同一集合中与上面获得的交集I2具有非空交集的其他文档的哈希值。
虽然我很喜欢 ArangoDB,但不幸的是它有自己的查询语言,而不是仅仅使用 SQL 所需的超集。在这种情况下,我发现我将不得不以某种方式将 FOR IN
与 FILTER
一起使用,但我完全不清楚如何使用。
作为SQL专家,我也曾与AQL的语法差异作过斗争。然而,它最终并没有变得那么难以理解,这使得 "learning" 只是时间和使用的函数。
我确定还有其他方法可以做到这一点,但这里有一个 quick/dirty 示例:
- 找到你要匹配的文档,并得到它的交集
- 对于
zuffs
中的每个文档 z
,计算交集并查找匹配项
- Return 匹配文档
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
Returns:
[
45
]
给定您的示例数据集,您只会得到一份满足要求 (45) 的文档。添加更多文档或修改其他文档之一以具有共同交集将提供更有趣的结果。
注意事项:
- 从 SQL 迁移到 AQL 会使您的思维从 "sets"(行数)转变为 "loops"(事物)。
- 跟踪 return(或本机)类型(数组与 object/string/etc。),并相应地处理每条数据(注意
FOR i IN INTERSECTION...
在 match
).
- 使用
Explain
和 Profile
按钮(或功能)查看查询的执行情况。想想其他的方法来完成这个结果,并尝试让它更快!
例如:
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
部分 return 相同的结果(具有单个值 3
的数组),但它们以不同的方式实现。而不是执行 FOR m IN match...
,我可以使用带有过滤器的本机数组函数。实际上,第一个示例比第二个示例快得多,原因在 "explain" 计划中很明显。
我发现它非常 有助于熟悉 high level and function 文档。这两个地方几乎包含您成功使用 AQL 所需的一切(除了 "big picture" 查询调优、索引等内容)。
我正在尝试使用 ArangoDB 来替代我目前使用的 Postgres。在 Postgres 中,我有一个 table、zuffs
包含具有以下形式的行
hash passes visits
123 {1,2,4} {2,3,4,5}
其中 passes
和 visits
都是 int[]
。为了建立 passes
和 visits 的交集,我会写
SELECT ARRAY
(
SELECT UNNEST(a1) INTERSECT SELECT UNNEST(a2))
FROM (SELECT passes AS a1,visits as a2 FROM zuffs where hash = 1) q;
Postgres 主动执行 return 结果 {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]}
我不清楚我将如何执行以下操作
- 为带有
hash
45. 的文档建立 - 取该结果和return同一集合中与上面获得的交集I2具有非空交集的其他文档的哈希值。
passes
和 visits
的交集 I1
虽然我很喜欢 ArangoDB,但不幸的是它有自己的查询语言,而不是仅仅使用 SQL 所需的超集。在这种情况下,我发现我将不得不以某种方式将 FOR IN
与 FILTER
一起使用,但我完全不清楚如何使用。
作为SQL专家,我也曾与AQL的语法差异作过斗争。然而,它最终并没有变得那么难以理解,这使得 "learning" 只是时间和使用的函数。
我确定还有其他方法可以做到这一点,但这里有一个 quick/dirty 示例:
- 找到你要匹配的文档,并得到它的交集
- 对于
zuffs
中的每个文档z
,计算交集并查找匹配项 - Return 匹配文档
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
Returns:
[
45
]
给定您的示例数据集,您只会得到一份满足要求 (45) 的文档。添加更多文档或修改其他文档之一以具有共同交集将提供更有趣的结果。
注意事项:
- 从 SQL 迁移到 AQL 会使您的思维从 "sets"(行数)转变为 "loops"(事物)。
- 跟踪 return(或本机)类型(数组与 object/string/etc。),并相应地处理每条数据(注意
FOR i IN INTERSECTION...
在match
). - 使用
Explain
和Profile
按钮(或功能)查看查询的执行情况。想想其他的方法来完成这个结果,并尝试让它更快!
例如:
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
部分 return 相同的结果(具有单个值 3
的数组),但它们以不同的方式实现。而不是执行 FOR m IN match...
,我可以使用带有过滤器的本机数组函数。实际上,第一个示例比第二个示例快得多,原因在 "explain" 计划中很明显。
我发现它非常 有助于熟悉 high level and function 文档。这两个地方几乎包含您成功使用 AQL 所需的一切(除了 "big picture" 查询调优、索引等内容)。