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

JS运行Mongoose脚本为何报读取null的addresses属性TypeError

问题描述

运行JS代码连接Mongoose操作MongoDB时抛出类型错误,执行命令及报错信息如下:

$ node user.js
mongo connection is open
D:\web development practice\mongoose_relationship\Models\user.js:44
    u.addresses.push({
      ^

TypeError: Cannot read properties of null (reading 'addresses')
    at addAddress (D:\web development practice\mongoose_relationship\Models\user.js:44:7)

对应业务代码如下:

const mongoose = require('mongoose');

mongoose.connect('mongodb://localhost:27017/relationshipDemo', { useNewUrlParser: true })
    .then(() => {
        console.log("mongo connection is open")
    })
    .catch(e => {
        console.log("oh no mongoose connection error");
        console.log(e);
    })

const userSchema = new mongoose.Schema({
    first: String,
    last: String,
    addresses: [{
        _id: { id: false },
        street: String,
        city: String,
        state: String,
        country: String
    }]
})

const User = mongoose.model('User', userSchema);

const makeUser = async () => {
    const u = new User({
        first: 'Harry',
        last: 'Potter'
    })
    u.addresses.push({
        street: 'baker street',
        city: 'london',
        state: 'london',
        country: 'uk'
    })
    await User.deleteMany();
    const res = await u.save();
    console.log(res);
}

const addAddress = async (id) => {
    const u = await User.findById(id);
    u.addresses.push({
        street: 'florida street',
        city: 'new york',
        state: 'new york',
        country: 'usa',
    })
    const res = await u.save();
    console.log(res);
}

addAddress('62ceae58cbb52805b8150ce9');
报错原因

报错核心是u.addresses.push这行里的u为null,即User.findById(id)没有查到匹配id的用户文档,直接返回了空值,共有3个相关问题:

  • 代码末尾只调用了addAddress,从未执行makeUser()方法,数据库里本身没有任何用户数据,自然查不到对应id的记录
  • 就算手动执行过makeUser(),Mongoose每次新建文档都会生成随机的唯一_id,硬编码传入的id62ceae58cbb52805b8150ce9和实际生成的用户id不匹配,查询结果必然为空
  • 存在schema写法错误:子文档配置禁用_id的正确写法为_id: false,原有写法_id: { id: false }是无效配置,不会生效
修复方法
  1. 数据库查询后必须增加空值判断,避免查不到数据时直接操作属性抛出异常
  2. 不要硬编码用户id,调整执行逻辑:先创建用户拿到生成的真实_id,再用这个id调用添加地址的方法
  3. 修正schema中子文档禁用_id的配置写法

修复后的可运行代码:

const mongoose = require('mongoose');

mongoose.connect('mongodb://localhost:27017/relationshipDemo', { useNewUrlParser: true })
    .then(() => {
        console.log("mongo connection is open")
    })
    .catch(e => {
        console.log("oh no mongoose connection error");
        console.log(e);
    })

const userSchema = new mongoose.Schema({
    first: String,
    last: String,
    addresses: [{
        _id: false, // 修正子文档_id禁用写法
        street: String,
        city: String,
        state: String,
        country: String
    }]
})

const User = mongoose.model('User', userSchema);

const makeUser = async () => {
    await User.deleteMany();
    const u = new User({
        first: 'Harry',
        last: 'Potter'
    })
    u.addresses.push({
        street: 'baker street',
        city: 'london',
        state: 'london',
        country: 'uk'
    })
    const res = await u.save();
    console.log('创建用户成功:', res);
    return res; // 返回创建好的用户文档,获取真实_id
}

const addAddress = async (id) => {
    const u = await User.findById(id);
    // 增加空值判断
    if (!u) {
        console.log('未找到对应用户');
        return;
    }
    u.addresses.push({
        street: 'florida street',
        city: 'new york',
        state: 'new york',
        country: 'usa',
    })
    const res = await u.save();
    console.log('添加地址成功:', res);
}

// 调整执行顺序,先创建用户再拿对应id添加地址
const run = async () => {
    const user = await makeUser();
    await addAddress(user._id);
}
run();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 12:18:31