情景
- 目前有三個表: 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 方式
