Arangodb AQL 连接、合并、嵌入嵌套的三个或更多集合
Posted
技术标签:
【中文标题】Arangodb AQL 连接、合并、嵌入嵌套的三个或更多集合【英文标题】:Arangodb AQL Joining, merging, embedding nested three collections or more 【发布时间】:2021-11-05 02:14:12 【问题描述】:我有以下集合,基于示例 Arangodb doc here,但添加了第三个名为 region 的集合
Users
"name" :
"first" : "John",
"last" : "Doe"
,
"city" : "cities/2241300989",
"_id" : "users/2290649597",
"_rev" : "2290649597",
"_key" : "2290649597"
Cities
"population" : 1000,
"name" : "Metropolis",
"region" : "regions/2282300990",
"_id" : "cities/2241300989",
"_rev" : "2241300989",
"_key" : "2241300989"
Regions
"name" : "SomeRegion1",
"_id" : "regions/2282300990",
"_rev" : "2282300990",
"_key" : "2282300990"
我想要一个像这样的目标结果
[
"user" :
"name" :
"first" : "John",
"last" : "Doe"
,
"_id" : "users/2290649597",
"_rev" : "2290649597",
"_key" : "2290649597"
,
"city" :
"population" : 1000,
"name" : "Metropolis",
"_id" : "cities/2241300989",
"_rev" : "2241300989",
"_key" : "2241300989",
"region" :
"name" : "SomeRegion1",
"_id" : "regions/2282300990",
"_rev" : "2282300990",
"_key" : "2282300990"
]
Arangodb 文档here 中的示例只有两个集合的查询
FOR u IN users
FOR c IN cities
FILTER u.city == c._id RETURN merge(u, city: c)
# However I want to have more than two collections e.g.
FOR u IN users
FOR c IN cities
For r IN regions
FILTER u.city == c._id and c.region == r._id RETURN merge(????????)
如上加入三个集合,您将如何获得结果?如果我想要第四个嵌套的会怎样?
【问题讨论】:
【参考方案1】:当您存储引用另一个集合的文档 _id
时,您可以利用 DOCUMENT
AQL 命令。
所以你的 AQL 查询变得更简单了,像这样:
FOR u IN users
LET city = DOCUMENT(u.city)
LET city_with_region = MERGE(city, region: DOCUMENT(city.region)
RETURN MERGE(u, city: city_with_region)
这个查询可以折叠得更多,但我把它留成这样,这样它就更能自我记录了。
DOCUMENT
的酷之处在于您只能返回文档的单个属性,例如 LET region_name = DOCUMENT(city.region).name
。
我还发现,在大多数情况下,执行子查询来定位文档的性能更高。
【讨论】:
请注意,原始查询不使用子查询,而是嵌套的FORs,类似于SQL中的JOIN。如果可能,这是首选解决方案,因为它通常比子查询或 DOCUMENT 函数调用执行得更好。此外,由于引入了拼接子查询,子查询的性能要好得多。您还应该注意,在集群中,带有 id 的 DOCUMENT 调用不能推送到 DB 服务器,而必须在协调器上执行。 顺便说一句,您也可以在使用嵌套查询或子查询时只返回一个属性。根据可能使用的索引,有问题的字段可能会从索引中获取,因此可能不需要加载完整的文档。但是,通过 DOCUMENT 调用获取文档总是会加载整个文档。 这真的取决于您的完整用例,当它超出此处发布的初始问题时。始终进行性能测试,关注 CPU/RAM/HDD 使用率、查询性能、单/集群性能、索引优化、数据存储重组以及从许多小文档到许多大文档的各种集合格式。每个人的里程会有所不同,测试和测试更多。 我同意您应该始终进行自己的性能测试。也就是说,嵌套 FOR 为查询优化器提供了最好的基础,因此应该几乎总是表现最好。 我有一些大型查询,200 多行 AQL,有趣的是,DOCUMENT 命令明显更快,尤其是在深度嵌套的循环中。我还尝试在查询中使用 Dictionary 样式对象生成来进行字典查找,但令人惊讶的是 DOCUMENT 命令比字典或嵌套 FOR 更快。测试显示了惊人的事情。【参考方案2】:大概是这样的:
FOR u IN users
FOR c IN cities
For r IN regions
FILTER u.city == c._id AND c.region == r._id
RETURN user: u, city: MERGE(c, region: r
您存储 id 而不是键来引用城市和地区是否有特殊原因? _id
只是一个虚拟字段,由集合名称前缀的 _key
组成(加上一个斜杠)。所以这同样有效(我故意省略了内部的 _id 和 _rev 字段):
Users
"name" :
"first" : "John",
"last" : "Doe"
,
"city" : "2241300989",
"_key" : "2290649597"
Cities
"population" : 1000,
"name" : "Metropolis",
"region" : "2282300990",
"_key" : "2241300989"
Regions
"name" : "SomeRegion1",
"_key" : "2282300990"
FOR u IN users
FOR c IN cities
For r IN regions
FILTER u.city == c._key AND c.region == r._key
RETURN user: u, city: MERGE(c, region: r
【讨论】:
谢谢你,但目标回报与我所寻找的不符。 为什么不匹配?它与您的预期结果有何不同?以上是关于Arangodb AQL 连接、合并、嵌入嵌套的三个或更多集合的主要内容,如果未能解决你的问题,请参考以下文章