在使用 Mongoose 操作 MongoDB 时,经常需要同时获取两个或多个集合中的数据。这时候就可以使用 MongoDB 中的 populate 方法,从而避免多次查询。不过,如果需要关联的字段比较多,populate 的使用就会变得非常繁琐。为此,Mongoose 提供了虚拟关联(Virtual Populate)的功能,可以在模式中定义一个虚拟字段,然后再通过 populate 轻松获取关联数据。
什么是 Virtual Populate
Virtual Populate 是 Mongoose 中的一项高级功能,它可以在模式定义的时候声明一个关联字段,然后通过 populate 把该字段关联的数据自动获取出来。与传统的 populate 不同的是,虚拟关联并不会在数据库中建立关联关系,而是在获取数据时使用 $lookup 去匹配其他集合的数据。
举个例子:
-- -------------------- ---- ------- ----- ---------- - --- ----------------- ----- ------- ------ -- ----- ------------------------------- ---- ------ -- --- ----- ---------- - --- ----------------- ------ ------- -------- ------ --- ----- ---- - ---------------------- ------------ ----- ---- - ---------------------- ------------ ------------------ -------- ------------------ ----------- ------- - ------------------------ --------------- --展开代码
在上面的例子中,我们通过 User 模式中的 posts 字段关联到了 Post 模式中的数据。不过如果 User 模式中需要关联的字段非常多,populate 方法的代码量就会非常的庞大。此时就可以使用虚拟关联去简化代码。
如何使用 Virtual Populate
使用虚拟关联有以下两个步骤:
定义虚拟关联字段
定义虚拟关联字段的方式与普通字段定义方法一样,我们只需要定义一个普通字段就可以了,只需要在 schema 中加 virtual()
方法即可,例如:
-- -------------------- ---- ------- ----- ---------- - --- ----------------- ----- ------ --- --------------------------- - ---- ------- ----------- ------ ------------- --------- -------- ----- --- ----- ---- - ---------------------- ------------展开代码
在上面的例子中,我们定义了一个虚拟关联字段 posts
,该关联字段关联到了 Post 模式中以 userId
为外键的数据。justOne 字段控制是否只关联一条数据。
使用 populate 抓取关联数据
虚拟关联字段定义好之后,就可以使用 populate 抓取关联数据了:
User.findOne({_id: userId}) .populate('posts') .exec((err, user) => { console.log(user.posts); //用户的所有帖子 });
例子
下面是一个完整的例子,通过使用虚拟关联和 populate,在查询用户的同时获取所有相关帖子的数据:
-- -------------------- ---- ------- ----- -------- - -------------------- ----- ------ - ---------------- ----- ---------- - --- -------- ------ ------- -------- ------- ------- - ----- ---------------------- ---- ------ - --- ----- ---------- - --- -------- ----- ------ --- --------------------------- - ---- ------- ----------- ------ ------------- --------- -------- ----- --- ----- ---- - ---------------------- ------------ ----- ---- - ---------------------- ------------ ----- -------- -------------------- - ----- ---- - ----- ------------------ --------------------------- ------------------ - ----- -------- ----- - ----- ------------------------------------------------------ ----- ------------- ------- ----- --- -------- -------- --- ------- ------------- ------- ----- --- -------- -------- --- ------- ------------- ------- ----- --- -------- -------- --- ------- ------------ --- ----- ------------- ------ ----- ---- ------ ----- --- --- ----- -------------------------- ---------------------- - ------展开代码
在上面的例子中,我们首先定义了两个模式,User 和 Post。然后在 User 模式中定义了一个虚拟关联字段 posts
,它关联到了 Post 模式中以 userId
为外键的数据。最后通过 getUserPosts
方法获取某个用户的所有帖子数据。在查询用户时使用了 populate 方法,这样返回的 user 数据就包含了该用户的所有帖子信息。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/67b6c3cc306f20b3a6301863