如何重新格式化数据仅用于使用Mongoose保存到MongoDB以避免"不是okForStorage"?

时间:2014-06-09 09:46:57

标签: javascript mongodb mongoose

我在Mongoose中定义了Schema,我只是意识到一个属性被保存为对象(一种哈希),但它可以在其键中包含禁止的字符。被禁止的是指MongoDB不太喜欢的那些,导致not okForStorage错误:点,美元符号等。

由于我不想更改我的所有应用程序,我想在我的模型上定义一些东西,在将对象传递给MongoDB之前将对象重新格式化为数组,当然,我还需要在加载此类数据时重新格式化它来自MongoDB。

我尝试了getter和setter,并在Middleware玩了一段时间,但无法使其正常工作。这是最好的做法吗?什么是最好的方法?我真的希望我可以在架构的某个地方粘贴两个函数,对于我的应用程序的其余部分它将是纯黑盒子。

更新:我想要实现的目标(例子):

toMongo = function (mapping) {
    // from {'k': 'v', ...} makes [{key: 'k', value: 'v'}, ...]
    return ...
}

fromMongo = function (mapping) {
    // from [{key: 'k', value: 'v'}, ...] makes {'k': 'v', ...}
    return ...
}

schema = mongoose.Schema({
    mapping: mongoose.Schema.Types.Mixed
});

var Foo = mongoose.model('Foo', schema);
var foo = new Foo({ mapping: {'tricky.key': 'yes', 'another$key': 'no'} });

foo.mapping // results in {'tricky.key': 'yes', 'another$key': 'no'}

foo.save(function(err, doc) {
   // mapping is actually saved as
   // [{key: 'tricky.key', value: 'yes'}, {key: 'another$key', value: 'no'}] in mongo!

   doc.mapping // results in {'tricky.key': 'yes', 'another$key': 'no'}
});

Foo.find(function (err, foos) {
    foos[0].mapping // results in {'tricky.key': 'yes', 'another$key': 'no'}
});

问题是:我应该在哪里挂钩我的两个魔术函数toMongofromMongo,这样界面的工作方式与示例中显示的完全相同?

(免责声明:在提出这个问题的时候,我是Mongoose& Node.js noob,所以即使是愚蠢的细节对我也有帮助)

1 个答案:

答案 0 :(得分:0)

我想我自己找到了答案。它可以用Middlewares解决,这样:

schema.post('init', function (doc) {
    doc.mapping = fromMongo(doc.mapping);
}

schema.pre('save', function (next) {
    this.mapping = toMongo(this.mapping);
    next();
}

这种方式与应用程序的其他部分非常隔离,到目前为止,我对此解决方案没有任何问题。如果出现任何问题,我会尽量不断更新这个答案。