You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Mongoose填充MongoDB嵌套数据,让评论显示用户名?

如何在MongoDB中通过Populate实现嵌套关联字段的查询需求?

定义的Schema结构

BlogSchema

const blogSchema = new mongoose.Schema({
  title: { type: String, required: true, minLength: 5 },
  author: String,
  user: {
    type: mongoose.Schema.Types.ObjectId,
    ref: "User",
  },
  comments: [
    {
      type: mongoose.Schema.Types.ObjectId,
      ref: "Comment",
    },
  ],
});

UserSchema

const userSchema = new mongoose.Schema({
  username: { type: String, required: true, unique: true, minLength: 4 },
  name: String,
  passwordHash: String,
  blogs: [
    {
      type: mongoose.Schema.Types.ObjectId,
      ref: "Blog",
    },
  ],
});

CommentSchema

const commentSchema = new mongoose.Schema({
  comment: { type: String, minLength: 5 },
  user: {
    type: mongoose.Schema.Types.ObjectId,
    ref: "User",
  },
  blog: {
    type: mongoose.Schema.Types.ObjectId,
    ref: "Blog",
    required: true,
  },
});

期望的查询结果格式

blog = {
  "title" : ".....",
  "author": "......",
  "user" : "user-Id",
  "comments": [
    {
      "comment":"....",
      "user": "username"
    }
  ]
}

当前尝试的代码

const blogs = await Blog.find({})
  .populate("user", { id: 1 })
  .populate("comments", { comment: 1, user: 1 });

问题

执行上述代码后,评论中的user字段显示的是用户ID,而非预期的用户名。

解决方案

需要使用嵌套Populate,在填充comments的同时,进一步填充其关联的user字段,并指定只返回用户名:

const blogs = await Blog.find({})
  .populate("user", { _id: 1 }) // 若你使用virtual id可替换为{ id: 1 }
  .populate({
    path: "comments",
    select: "comment user", // 仅保留comment和user字段
    populate: {
      path: "user",
      select: "username -_id" // 仅返回username并排除_id,使user直接为用户名字符串
    }
  });

说明

  • 嵌套Populate通过对象形式配置populate参数,先指定comments的填充规则,再在其中配置关联user的填充规则。
  • select: "username -_id"的作用是只选取username字段,同时排除_id,让返回的user字段直接是用户名的字符串值,而非包含_id的用户对象。

内容的提问来源于stack exchange,提问作者Tajpuriya

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 10:43:19