MongoDB 多表關聯查詢


情景

  • 目前有三個表: articles(文章) users(用戶) comments(評論),表結構如下:
  1. articles
    title: String,// 文章標題
    content: String,// 文章內容
    read: {    // 文章閱讀量
      type: Number,
      default: 0,
    },
    star: {// 文章點贊量
      type: Number,
      default: 0,
    },
    comment: {// 文章評論量
      type: Number,
      default: 0,
    },
    authorId: String,// 文章作者
    
  2. users
    username: String,// 用戶名
    avatar: String,// 頭像
    gender: String,// 性別
    phone: String,// 手機號
    email: String,// 郵箱
    password: {    // 密碼
      type: String,
      select: false,
    },
    
  3. 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 關聯查詢

    1. 定義 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;
      
    2. 使用 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 方式

參考文獻:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM