改变Mongoose中的鉴别器值/鉴别类型

时间:2017-05-29 21:03:00

标签: node.js mongodb mongoose discriminator

我通过两个模型和一个鉴别器键(简单示例)表示了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)用户的所有实例。

谢谢!

2 个答案:

答案 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);
};