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

Mongoose Populate无法获取嵌套数组?技术问题求助

问题排查与解决

问题场景

现有以下Mongoose Schema:

Categories Schema

const CategoriesSchema = new mongoose.Schema(
  {
    sites: [
      {
        site: {
          type: ObjectId,
          ref: "Sites",
        }
      }
    ],
  }
);

mongoose.model("Categories", CategoriesSchema, 'organizer-categories');

Sites Schema

const SitesSchema = new Schema({
  url: {
    type: String,
    required: true,
  },
  img: {
    type: String,
  },
});
mongoose.model("Sites", SitesSchema, "organizer-sites");

编写了addSite函数,意图创建新Site并添加到对应Category,同时通过populate返回包含完整Site数据的更新后Category,但实际仅返回Site的_id:

exports.addSite = async (req, res) => {
const {categoryId, siteUrl} = req.body;
console.log('categoryId, siteUrl', categoryId, siteUrl)

try {

    let  site = await Sites.findOne({url: siteUrl});

    console.log('site', site)

    if(site) {
        return res.status(422).send(`${siteUrl} already exists.`)
    }

     site = await Sites.create({url: siteUrl, categoryId});
    //  site = {url: siteUrl, categoryId};

     const category = await Categories.findOneAndUpdate({
        _id: categoryId
    }, {
        $addToSet: {
            sites: site
        }
    }, {
        new: true
    }).populate({
        path: 'sites.site',
        model: 'Sites'
    })

 
   console.log('category', category)
    res.status(201).json(category);
} catch(error) {
    console.error(error);
    return res.status(500).send('Error adding category.')    
}

原因分析

问题核心在于$addToSet的参数结构不符合Schema定义:

  • CategoriesSchema的sites数组要求存储{site: ObjectId}格式的关联对象
  • 当前代码直接传入完整的site文档,导致MongoDB中Categories的sites数组存储的是完整Site文档,而非预期的关联结构
  • 后续populate({path: 'sites.site'})无法在数组元素中找到site字段,因此无法完成关联数据填充,最终仅返回文档自身的_id

另外注意:SitesSchema未定义categoryId字段,创建Site时传入该字段属于无效参数,不会被存入数据库。

解决方法

修改$addToSet的参数,传入符合CategoriesSchema结构的关联对象,仅将Site的_id赋值给site字段,同时移除无效的categoryId参数:

exports.addSite = async (req, res) => {
const {categoryId, siteUrl} = req.body;
console.log('categoryId, siteUrl', categoryId, siteUrl)

try {

    let  site = await Sites.findOne({url: siteUrl});

    console.log('site', site)

    if(site) {
        return res.status(422).send(`${siteUrl} already exists.`)
    }

    // 移除无效的categoryId参数
     site = await Sites.create({url: siteUrl});

     const category = await Categories.findOneAndUpdate({
        _id: categoryId
    }, {
        // 传入符合Schema结构的关联对象
        $addToSet: {
            sites: { site: site._id }
        }
    }, {
        new: true
    }).populate({
        path: 'sites.site',
        model: 'Sites'
    })

 
   console.log('category', category)
    res.status(201).json(category);
} catch(error) {
    console.error(error);
    return res.status(500).send('Error adding category.')    
}

修改后,Categories的sites数组会正确存储关联结构,populate方法可正常找到关联路径,返回包含完整Site数据的Category对象。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 07:50:26