Nodejs mongoose 映射完后 console.log(对象) 输出不了里面的属性值啊?

Nodejs mongoose 映射完后 console.log(对象) 输出不了里面的属性值啊?

例如 a对象是mongoose映射后的, a.myDefineObj = {‘name’:‘aaa’}; console.log(a); 输出的信息还是a对象mongoose定义好的属性,而myDefineObj 属性没有输出来,但console.log(a.myDefineObj)是有的。 是不是mongoose对象重写了toString 方法?

那是这样 ,我用res.send({a:a});前端接受到的这个对象,为啥没有myDefineObj属性呢,输出时undefind。


3 回复

这个问题涉及到 Mongoose 对象的行为以及如何正确地访问和序列化这些对象。Mongoose 对象在某些情况下可能会表现出一些特殊的特性,比如只读属性或延迟加载的属性。

示例代码

假设我们有一个简单的 Mongoose 模型定义:

const mongoose = require('mongoose');
const Schema = mongoose.Schema;

// 定义一个简单的模型
const UserSchema = new Schema({
    name: String,
    age: Number
});

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

// 创建一个新的用户实例
const newUser = new User({
    name: 'John Doe',
    age: 30
});

// 添加自定义属性
newUser.myDefineObj = { name: 'aaa' };

module.exports = User;

接下来,在你的应用中使用这个模型:

const express = require('express');
const app = express();
const User = require('./models/User'); // 假设你的模型文件路径为 models/User.js

app.get('/test', async (req, res) => {
    const user = await User.findOne(); // 假设你已经有一些数据
    user.myDefineObj = { name: 'aaa' };
    
    // 直接打印对象
    console.log(user); // 这里可能不会显示 `myDefineObj` 属性
    
    // 尝试序列化并发送给前端
    res.json(user);
});

app.listen(3000, () => {
    console.log('Server is running on port 3000');
});

解释

  1. 对象输出问题

    • 当你使用 console.log(user) 时,Mongoose 对象可能不会自动包含所有属性。这是因为 Mongoose 在某些情况下会延迟加载某些属性(如虚拟属性、嵌入式文档等)。
    • 如果你直接打印对象,可能看不到 myDefineObj 属性,因为 Mongoose 可能没有将该属性解析为实际的 JavaScript 对象属性。
  2. 序列化问题

    • 当你尝试通过 res.json(user) 发送对象时,Express 会调用 JSON.stringify() 来序列化对象。此时,如果 myDefineObj 属性未被正确解析为普通对象属性,它可能不会出现在序列化的 JSON 中。

解决方法

  • 确保所有属性都被正确解析:你可以手动将 Mongoose 对象转换为普通的 JavaScript 对象,然后再进行操作。
const plainUser = user.toObject(); // 将 Mongoose 对象转换为普通 JavaScript 对象
plainUser.myDefineObj = { name: 'aaa' };
console.log(plainUser); // 现在应该能看到 myDefineObj 属性
res.json(plainUser); // 发送给前端的数据也会包含 myDefineObj 属性

这样可以确保你获取的是一个普通的 JavaScript 对象,而不是 Mongoose 特殊处理的对象。


不能顶啊》

在使用 Mongoose 时,如果你发现 console.log(a) 没有输出你自定义的属性(如 myDefineObj),这通常是因为 Mongoose 在调用 console.log 时只显示了文档的基本数据,而不是所有属性。Mongoose 文档对象在被转换为普通 JavaScript 对象或 JSON 对象时才会包含所有属性。

示例代码

假设我们有一个 User 模型,其中包含一些默认属性和一个自定义属性:

const mongoose = require('mongoose');

mongoose.connect('mongodb://localhost/test', { useNewUrlParser: true, useUnifiedTopology: true });

const userSchema = new mongoose.Schema({
    name: String,
    age: Number
});

userSchema.methods.setMyDefineObj = function (obj) {
    this.myDefineObj = obj;
};

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

// 创建一个新用户并设置自定义属性
const newUser = new User({ name: 'John Doe', age: 30 });
newUser.setMyDefineObj({ name: 'aaa' });

// 保存用户
newUser.save((err) => {
    if (err) throw err;

    // 查询用户
    User.findById(newUser._id, (err, foundUser) => {
        if (err) throw err;

        // 输出整个对象
        console.log(foundUser);  // 输出基本属性,可能不包括 myDefineObj

        // 输出特定属性
        console.log(foundUser.myDefineObj);  // 正确输出 { name: 'aaa' }

        // 将 Mongoose 文档转换为普通对象
        const regularObject = foundUser.toObject();
        console.log(regularObject);  // 现在会包含 myDefineObj 属性
    });
});

解释

  1. Mongoose 文档对象:当你从数据库中查询一个 Mongoose 文档时,默认情况下,它不会包含所有自定义属性,除非你在查询时明确指定这些属性。

  2. toObject() 方法:通过调用 toObject() 方法,你可以将 Mongoose 文档对象转换为普通的 JavaScript 对象,这样就可以访问所有的属性了。

  3. console.log 和响应对象:当你将 Mongoose 文档直接传递给 console.logres.send 时,它们只会显示基础数据。你需要将其转换为普通对象才能看到所有属性。

希望这个解答对你有帮助!

回到顶部