MongoDB用Mongoose得到的对象不能增加属性完美解决方法(两种)

1. 简介

在使用MongoDB数据库时,Mongoose是一个非常流行的ORM库。可以通过Mongoose将MongoDB转换成具有模型层的数据库。但是,在使用Mongoose过程中,我们会遇到一些问题,特别是在对象创建和更新过程中。其中一个常见的问题是,在从Mongoose得到的对象中增加自定义属性时,该属性始终为undefined。这篇文章将介绍两种解决方法。

2. 问题描述

当我们从Mongoose得到一个对象时,这个对象是一个Mongoose模型的实例。当我们尝试为这个对象添加自定义属性时,我们会发现这个新属性不能被正确保存到数据库中。以下是一个简单的例子:

const mongoose = require("mongoose");

const Schema = mongoose.Schema;

const UserSchema = new Schema({

name: String,

email: String

});

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

const user = new User({

name: "Alice",

email: "alice@example.com"

});

user.phoneNumber = "555-1234";

user.save().then(() => console.log("User saved!"));

这将会输出"User saved!",但是phoneNumber属性并没有被保存到数据库中。

3. 解决方法一

3.1 Object.assign()

一种解决方法是使用JavaScript中的Object.assign()方法,将Mongoose对象转换成普通JavaScript对象并在此对象上添加属性。这个新的JavaScript对象可以直接被保存到MongoDB数据库中。

const mongoose = require("mongoose");

const Schema = mongoose.Schema;

const UserSchema = new Schema({

name: String,

email: String

});

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

const user = new User({

name: "Alice",

email: "alice@example.com"

});

const userObj = user.toObject();

userObj.phoneNumber = "555-1234";

User.update({ _id: user.id }, userObj).then(() => console.log("User saved!"));

在上面的代码中,我们首先使用user.toObject()将Mongoose对象转换成普通JavaScript对象。然后我们在这个新的JavaScript对象上添加一个phoneNumber属性。最后,我们使用MongoDB的update方法将这个新的JavaScript对象保存到数据库中。

3.2 toJSON()

另一种解决方法是使用Mongoose中的toJSON()方法,将一个Mongoose对象转换为一个普通的JavaScript对象。这个新的JavaScript对象可以直接被保存到MongoDB数据库中。

const mongoose = require("mongoose");

const Schema = mongoose.Schema;

const UserSchema = new Schema({

name: String,

email: String

});

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

const user = new User({

name: "Alice",

email: "alice@example.com"

});

const userObj = user.toJSON();

userObj.phoneNumber = "555-1234";

User.update({ _id: user.id }, userObj).then(() => console.log("User saved!"));

在上面的代码中,我们首先使用user.toJSON()将Mongoose对象转换成普通JavaScript对象。接着我们在这个新的JavaScript对象上添加一个phoneNumber属性。最后,我们使用MongoDB的update方法将这个新的JavaScript对象保存到数据库中。

4. 解决方法二

4.1 Mongoose Schema 预设属性 .set()

另一种解决该问题的方法是使用Mongoose的预设属性 .set()。使用这个方法可以让我们在添加新的属性时不需要使用toJSON()或者Object.assign()方法。

const mongoose = require("mongoose");

const Schema = mongoose.Schema;

const UserSchema = new Schema({

name: String,

email: String

});

UserSchema.set("toObject", {

virtuals: true,

transform: function(doc, ret, options) {

ret.id = ret._id;

delete ret._id;

delete ret.__v;

}

});

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

const user = new User({

name: "Alice",

email: "alice@example.com"

});

user.phoneNumber = "555-1234";

user.save().then(() => console.log("User saved!"));

在上面的代码中,我们使用UserSchema.set()方法为我们的UserSchema添加了一个toObject预设属性。这个预设属性告诉Mongoose将虚拟属性(virtuals)赋值给新的JavaScript对象,并且使用transform函数删除不需要的属性。这意味着当我们添加自定义属性时,这些属性将被包含在Mongoose对象的toObject()和toJSON()方法中,并正确地保存到数据库中。

4.2 Mongoose Schema 预设属性 .virtual()

另一个方法是使用Mongoose的预设属性 .virtual()。使用这个方法我们可以在Mongoose对象中添加虚拟属性,这些属性将包含在Mongoose对象的toObject()和toJSON()方法中,并且正确地保存到数据库中。

const mongoose = require("mongoose");

const Schema = mongoose.Schema;

const UserSchema = new Schema({

name: String,

email: String,

phoneNumber: {

type: String,

virtual: true,

set: function (value) {

this._phoneNumber = value;

},

get: function() {

return this._phoneNumber;

}

}

});

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

const user = new User({

name: "Alice",

email: "alice@example.com"

});

user.phoneNumber = "555-1234";

user.save().then(() => console.log("User saved!"));

在上面的代码中,我们使用UserSchema.virtual()方法为Mongoose模式添加虚拟属性phoneNumber。这个属性在Mongoose对象中的名称是_phoneNumber。我们使用set()方法将值存储在_phoneNumber属性中,并使用get()方法取回值。最后,我们将phoneNumber设置为"555-1234"并将用户对象保存到数据库中。

5. 结论

本文介绍了四种解决在Mongoose中添加自定义属性不被正确保存到数据库中的方法。第一种是使用toJSON()和Object.assign()方法。第二种是使用Mongoose Schema的预设属性.set()和预设属性.virtual()。每种方法都有其优点和缺点,可以根据具体情况进行选择。希望本文能够帮助您在使用Mongoose时正确地添加自定义属性。

数据库标签