在NodeJ中,当在同一模式上编译多个Mongoose模型时,MongoDB的“唯一”模式类型选项未实现。
1)从定义模式的Node.Js模块中导出Mongoose模型时,将按预期执行Mongoose模式验证。
// sandboxUser.js
const mongoose = require("mongoose");
let Schema = mongoose.Schema;
let sandboxUserSchema = new Schema(
{
name: {type: String, required: true},
email: {type: String, required: true, unique: true, index: true},
}
);
module.exports = mongoose.model('SandboxUser', sandboxUserSchema);
任何违反上述架构约束的尝试都会引发错误E11000:只需多次运行以下代码段
// mongodb.test.js
mongoose.connect('[your-dbURL]');
let SandboxUser = require('./sandboxUser');
let origUser = new SandboxUser();
origUser.name = 'username';
origUser.email = 'username@example.com';
origUser.save(function (err) {
console.log(err); // E11000 duplicate key error
});
2)但是,在相同的架构上创建新模型无法按预期工作:不再满足MongoDB的“唯一”架构类型选项。
注释掉前面的代码段,然后多次运行下面的代码段。尽管电子邮件属性值相同,也会将多个文档添加到集合中。
// mongodb.test.js
// Extend the schema and create a new model ‘NewSandboxUser’
// ‘unique’ schema type option validation is not performed
// on the collection ‘newsandboxusers'
mongoose.connect('[your-dbURL]');
let SandboxUser = require('./sandboxUser');
let userSchema = SandboxUser.schema;
userSchema.add({newField: String});
let NewSandboxUser = mongoose.model('NewSandboxUser', userSchema);
// Make sure that the email property is still ‘unique:true'
let newSchemaPaths = mongoose.model('NewSandboxUser').schema.paths;
console.log(newSchemaPaths.email.options.unique); // true
// Save the same document repeatedly, to violate the schema's constraints.
let user = new NewSandboxUser();
user.name = ‘newusername';
user.email = ‘username@example.com';
user.save(function (err) {
console.log(err); // null. Should be: E1100
});
证明:在shell中运行mongo
$ mongo
> use [your-dbURL];
> db.newsandboxusers.find();
{ "_id" : ObjectId("5b6e82096155e921e9c1eac3"), "name" : “newusername", "email" : "username@example.com", "__v" : 0 }
{ "_id" : ObjectId("5b6e82096155e921e9c1eac4"), "name" : “newusername", "email" : "username@example.com", "__v" : 0 }
在这种情况下,为什么架构验证未按预期执行?
如果需要,可以创建一个Github项目来演示上述内容。
(经过测试的猫鼬版本:4.13.14和5.2.7)