我通过两个模型和一个鉴别器键(简单示例)表示了Mongoose中的类层次结构:
var options = {discriminatorKey: 'kind'};
var UserSchema = new mongoose.Schema({
username: {type: String, index: true},
// some other fields
}, options);
// some schema methods
var User = mongoose.model('User', UserSchema);
var PowerUserSchema = new mongoose.Schema({
username: {type: String, index: true},
// some other fields
rank: {type: String}
}, options);
var PowerUser = User.discriminator('PowerUser', PowerUserSchema);
到目前为止,这个工作正常,但是我遇到了这种情况,我想在那里推广"用户到PowerUser。我最初的想法是设置" kind"用户的属性并在实例上调用save(),希望下次检索到值后,将返回正确的mongoose类型:
var user = ... // retrieve user
user.kind = 'PowerUser';
user.save();
user = ... // retrieve user again
这似乎不起作用,因为" kind"值未保存到实例。我遇到了this建议,遗憾的是,它没有更新鉴别器值。
我现在的问题是:我是否走在正确的轨道上?更新鉴别器值甚至允许这样的情况,或者我应该以不同的方式更好地构造我的数据(例如,使用单个模式,使用"类型"条目指定每个实例是什么;这会产生这样的影响:对于降级案例,不会丢失任何信息。)
此外,pro(de)moting用户不应该破坏我的数据库中引用(Power)用户的所有实例。
谢谢!
答案 0 :(得分:1)
最后,我通过这样做来实现这一目标:
var user = ... // retrieve user
var powerUser = PowerUser.hydrate(user.toObject());
powerUser.kind = 'PowerUser';
powerUser.save();
powerUser = ... // retrieve user again
另一方面,将PowerUser降级回用户似乎没有这样做。
答案 1 :(得分:0)
您是否尝试在模型
上使用 findOneAndUpdate User.findOneAndUpdate({_id: _user._id}, {$set: {kind: "PowerUser"}, {new: true}, function (err, doc) {
should.not.exist(err);
should.exist(doc.kind);
doc.kind.should.equal('PowerUser');
done();
});
如果您还需要删除已设置的属性,可以使用这样的静态方法。值new:true是获取新修改的文件而严格:false所以你可以取消设置UserSchema上尚未存在的值
changes = {kind: "PowerUser"}
UserSchema.statics.switchKind = function (id, changes, callBack) {
const unset = {
rank: undefined,
someOtherField: undefined
};
return this.findOneAndUpdate({_id: id}, {$set: changes, $unset: unset}, {new: true, strict: false}, callBack);
};