情景
- 目前有三个表: articles(文章) users(用户) comments(评论),表结构如下:
- articles
title: String,// 文章标题 content: String,// 文章内容 read: { // 文章阅读量 type: Number, default: 0, }, star: {// 文章点赞量 type: Number, default: 0, }, comment: {// 文章评论量 type: Number, default: 0, }, authorId: String,// 文章作者
- users
username: String,// 用户名 avatar: String,// 头像 gender: String,// 性别 phone: String,// 手机号 email: String,// 邮箱 password: { // 密码 type: String, select: false, },
- comments
content: String,// 评论的内容 articleId: String,// 文章id,外键 authorId: String,// 文章作者,外键 userId: String,// 当前用户
实现多表关联,查询comments表时,将对应的文章作者(通过authorId在users表里找到)和文章详情(通过articleId在articles表里找到)一起返回
-
第一种方式 使用 aggregate 管道聚合查询
// 查询评论详情 const findComment = async (ctx) => { const { id } = ctx.params; const comment= await Comment.aggregate([ { $lookup: { from: "articles", // 关联 articles 表 localField: "articleId", // 根据 comments 里 articleId 字段查询 foreignField: "_id", // 查找 articles 表里对应的 _id 的数据 as: "articles",// 返回的字段别名 }, }, { $lookup: { from: "users", // 关联 users 表 localField: "authorId", // 根据 comments里 authorId 字段查询 foreignField: "_id", // 查找 users 表里对应的 _id 的数据 as: "author",// 返回的字段别名 }, }, // 创建一个 mongoDB 的 ObjectId: mongoose.Types.ObjectId { $match: { _id: mongoose.Types.ObjectId(id) } }, ]); }
-
第二种方式 使用 populate 关联查询
-
定义 Comment 模型,在定义模型时,需要使用 ref 来引用要关联的模型
const mongoose = require("mongoose"); const schame = new mongoose.Schema({ content: String,// 评论的内容 articleId: { type: mongoose.Schema.Types.ObjectId, ref: "Article", // 文章模型的名称 },// 文章id,外键 authorId: { type: mongoose.Schema.Types.ObjectId, ref: "User", // 用户模型的名称 },// 文章作者,外键 userId: String,// 当前用户 }) const Comment = mongoose.model("Comment", schame, "comments"); module.exports = Comment;
-
使用 populate查询,引入所有关联的模型
const Comment = require("../models/comment"); const Article = require("../models/article"); const User = require("../models/user"); // 查询评论详情 const findComment = async (ctx) => { const { id } = ctx.params; const comment= await Comment.findOne({ _id: id }).populate("articleId").populate("authorId").lean() ctx.body = { comment } }
-
总结
- MongoDB 经常用到的就是这两种方式,populate 方式需要 MongoDB 版本号 > 3.2
- 推荐使用 aggregate 方式