我使用Mongoose为Person
和Transaction
个集合建模,其中每个Transaction
将引用两个不同的Person
个实例:
var TransactionSchema = new Schema({
, amount : { type: Number, required: true }
, from : { type: ObjectId, required: true }
, to : { type: ObjectId, required: true }
, date : Date
});
var PersonSchema = new Schema({
name : { type: String, required: true }
, transactions : [ObjectId]
});
我希望每个Person
都包含所有Transaction
的集合,它们是to
或from
的值。到目前为止,这是我能够弄清楚如何做到这一点的最佳方式:
TransactionSchema.pre('save', function(next, done) {
var transaction = this;
Person.findById(this.to, function (err, person) {
person.transactions.push(transaction);
person.save();
});
Person.findById(this.from, function (err, person) {
person.transactions.push(transaction);
person.save();
});
next();
});
这似乎过分了。有没有更好的方法来做到这一点,还是我试图像关系数据库那样使用MongoDB?我应该直接查询Transaction
集合,而不是与Person
个实例关联的Translation
集合吗?
谢谢。
答案 0 :(得分:7)
在设计MongoDB架构时,您必须更多地考虑要在数据库上执行的查询。
尝试复制数据以提高速度并引用它以保证完整性。这是什么意思?
那么,例如当你查询一个事务时,我猜你不需要第一次没有所有的用户细节吗? (在交易中显示信息时,您是否需要用户的电子邮件,位置?)
我想你可能只需要用户ID和用户名,所以你应该这样做:
var TransactionSchema = new Schema({
, amount : { type: Number, required: true }
, from : {
user_id: {
type: ObjectId
, required: true
}
, username: {
type: String
, required: true
}
}
, to : {
user_id: {
type: ObjectId
, required: true
}
, username: {
type: String
, required: true
}
}
, date : Date
});
因此,对于显示交易详细信息的页面(一个用于事务,另外两个用于用户名的查询),不是对显示3个查询,而是只有一个。 这只是一个示例,您可以为User模式应用相同的逻辑,具体取决于您要实现的目标。
无论如何,我不认为你的中间件是好的,因为你没有检查那里的错误(无论如何你总是打电话给下一个)。这就是我编写中间件的方式(没有测试,但这个想法很重要):
TransactionSchema.pre('save', function(next, done) {
var transaction = this;
Person.where('_id').in([this.to, this.from]).run(function (err, people) {
if (people.length != 2) { next(new Error("To or from doesn't exist")); return; }
Step(
function save_to() {
people[0].transactions.push(transaction);
people[0].save(this);
},
function save_from(err) {
if (err) { next(err); return; }
people[1].transactions.push(transaction);
people[1].save(this);
},
function callback(err) {
next(err);
}
);
});
});
在上面的代码中,我使用Step库进行流量控制,我只使用一个查询而不是两个(当搜索“to”和“from”时)。