MongoDB $ lookup:限制和用法

Dav*_*New 7 mongodb mongodb-query

通过新的聚合管道阶段,$lookup我们现在可以执行"左外连接".

乍一看,我想立即用两个独立的集合替换我们的一个非规范化集合,并$lookup在查询时使用它们加入它们.这将解决在必要时更新大量文档的问题.现在我们只能更新一个文档.

但这肯定太好了,不是真的吗?毕竟这是一个NoSQL文档数据库!

MongoDB的首席技术官也强调了他的担忧:

我们仍然担心$ lookup可能被误用来像对待关系数据库一样对待MongoDB.但是,我们不是限制其可用性,而是帮助开发人员知道它的使用何时适当,以及何时它是反模式.在接下来的几个月中,我们将超越现有文档,为该领域提供明确,有力的指导.

有什么限制$lookup 我可以在实时,操作性地查询我们的数据时使用它们,还是应该将它们留给报告,离线情况?

Jos*_*eam 5

我和你一样对$lookup.

我认为有取舍。SQL 数据库的主要关注点之一(这也是 NoSQL 起源的原因之一)是大规模连接可能需要大量时间(相对而言)。

它绝对有助于为您的数据提供一个声明性模型,但是如果您开始将整个 NoSQL 数据库建模为行和表的数据库(ref例如,仅使用s),那么您就开始建模它,就好像它是只是一个 SQL 数据库(在某种程度上)。甚至 MongoDB 也提到了它(就像你在问题中提出的那样):

我们仍然担心 $lookup 可能会被滥用,将 MongoDB 视为关系数据库。

你提到:

这将解决在必要时更新大量文档的问题。现在我们只能更新一个文档。

我不确定您的收藏集究竟是什么样子,但这听起来绝对可以很好地用于$lookup.

我可以在实时操作查询中使用它们吗

我想再说一遍,这取决于您的用例。你必须比较:

  • 查询的所需语义(声明式 vs 命令式)
  • $lookup在某些情况下将您的数据建模为更具相关性(并因此使用)是否值得在计算时间上进行潜在的权衡(假设跨集合查询甚至是需要关注的,从计算上讲)

等等...

我相信在接下来的几个月里我们会看到“左外连接”的性能测试,也许 MongoDB 会开始写一些关于何时$lookup是反模式的文章。

希望这个答案有助于增加讨论。


sty*_*ane 5

首先,MongoDB 是一个基于文档的数据库,并且永远都是。因此$lookup3.2 版中新增的聚合管道阶段并没有像 MongoDB 的 CTO 提到的那样将 MongoDB 更改为关系数据库 (RDBMS):

我们仍然担心 $lookup 可能会被滥用,将 MongoDB 视为关系数据库。

$lookup文档中提到的第一个限制是:

对同一数据库中的未分片集合执行左外部联接,以从“联接”集合中过滤文档以进行处理。

这意味着您不能将它与分片集合一起使用。

此外,该$lookup运算符不直接使用帖子中提到的数组,因此如果它是数组,您将需要一个初步$unwind阶段来非规范化localField

现在你说:

这将解决在必要时更新大量文档的问题。

如果您的数据更新频繁而不是读取,这是一个好主意。正如MongoDB 模式设计的 6 条经验法则:第 3 部分中所述,尤其是当您拥有大型分层数据集时。

如果这些字段的读取频率比更新频率高得多,则对一个或多个字段进行非规范化是有意义的。

我相信通过仔细的架构设计,您可能不需要$lookup运算符。