MongoDB是一种非关系型数据库,它不支持传统的SQL语言,也没有像join这样的操作来实现多表查询。那么,如果我们想要在MongoDB中查询三个或更多的集合(collection)之间的关联数据,该怎么办呢?
幸运的是,MongoDB提供了一个强大的聚合管道(aggregation pipeline)功能,它可以对集合中的文档(document)进行各种复杂的转换和处理,从而实现类似于SQL中的分组、排序、过滤、聚合等操作。其中,一个重要的操作符就是$lookup,它可以让我们在聚合管道中引入其他集合的数据,从而实现多表查询。
$lookup操作符有两种语法形式,一种是简单形式,一种是扩展形式。简单形式适用于两个集合之间的一对多或一对一的关联查询,扩展形式则可以支持更复杂的情况,比如多对多、自连接、条件连接等。在本文中,我们主要介绍扩展形式的$lookup操作符,以及如何用它来实现三表查询。
假设我们有三个集合:students、courses和scores,分别存储了学生、课程和成绩的信息。每个集合的文档结构如下:
我们想要查询每个学生选修了哪些课程,以及每门课程的成绩和老师。这就涉及到了三个集合之间的关联查询。我们可以使用以下聚合管道来实现:
解释一下这个聚合管道的逻辑:
1.首先,我们从students集合开始,对每个学生文档进行处理。
2.然后,我们使用$lookup操作符,从scores集合中引入与当前学生文档的_id相等的成绩文档。这里我们使用了扩展形式的$lookup语法,它有四个参数:
3.from: 指定要引入的集合的名称,这里是scores。
4.let: 定义一个变量,用来存储当前学生文档的_id值,这里我们命名为student_id。
5.pipeline: 定义一个子聚合管道,用来对引入的集合进行过滤和处理。这里我们使用了两个操作符:
$match: 过滤出与当前学生文档的_id相等的成绩文档。这里我们使用了$expr操作符,它可以让我们在$match中使用聚合表达式。我们使用了$eq操作符,比较成绩文档中的student_id字段和当前学生文档中定义的student_id变量是否相等。