mongoose:如何build模一个外键/逆关系?

我正在使用Mongoose来模拟PersonTransaction集合,其中每个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的集合,他们要么是价值的。 到目前为止,这是我已经能够找出如何做到最好的方式:

 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? 我应该直接查询Translation集合,而不是收集与每个Person实例关联的Transaction

谢谢。

在deviseMongoDB模式时,您需要更多地考虑您要在数据库上执行的查询。

尝试复制数据的速度,并参考它的完整性。 那是什么意思?
那么,例如,当你对一个事务进行查询时,我猜你不需要第一次使用所有的用户细节呢? (在交易中显示信息时是否需要用户的电子邮件地址?)
我想你可能需要用户名和用户名,所以你应该这样做:

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

因此,而不是做三个查询页面显示交易细节(一个用于交易和2个额外的用户名查询),你将只有一个。
这仅仅是一个例子,你可以对用户模式应用相同的逻辑,这取决于你想要达到的目标。

无论如何,我不认为你的中间件是好的,因为你不是在那里检查错误(你总是打电话给下一个,不pipe是什么)。 这是我如何写中间件(没有testing,但这个想法是重要的):

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

在上面的代码中,我使用的步骤库进行stream量控制,我只使用一个查询而不是两个(当search“到”和“从”)。