我是mongoDB和Mongoose的新手,我在关系方面遇到了一些问题。我的架构有3个表(用户/人/家庭),你可以在下面看到它。
var mongoose = require('mongoose')
, Schema = mongoose.Schema
var userSchema = Schema({
_id : Schema.Types.ObjectId,
email : String,
person : [{ type: Schema.Types.ObjectId, ref: 'Person' }] // A user is linked to 1 person
});
var personSchema = Schema({
_id : Schema.Types.ObjectId,
name : String,
user : [{ type: Schema.Types.ObjectId, ref: 'User' }] // A person is linked to 1 user
families : [{ type: Schema.Types.ObjectId, ref: 'Family' }] // A person have 1,n families
});
var familySchema = Schema({
_id : Schema.Types.ObjectId,
name : String,
persons : [{ type: Schema.Types.ObjectId, ref: 'Person' }] // A family have 0,n persons
});
var User = mongoose.model('User', userSchema);
var Person = mongoose.model('Person', personSchema);
var Family = mongoose.model('Family', familySchema);
我不知道我的架构是否良好,我的person
中是否需要参数userSchema
?因为信息将被复制,在userSchema
中我将拥有personID,而在personSchema
中,这将是userID。
如果我理解为我的请求提供这些重复值很有用吗?但是如果信息是重复的,我需要执行两个查询来更新这两个表吗?
例如,如果我有一个家庭成员(personSchema中的家庭参数),并且在家庭中我有这个人(familySchema中的人员参数)。删除/更新表格中的行的请求是什么?
谢谢
恕我直言,如果满足您的需求,您的架构似乎很好! (虽然,如果你认为你当前的架构满足了你的目的而没有臃肿,那么它是好的)..
var userSchema = Schema({
_id : Schema.Types.ObjectId,
email : String,
person : { type: Schema.Types.ObjectId, ref: 'Person' } // A user is linked to 1
//person // Here I have removed the []
});
var personSchema = Schema({
_id : Schema.Types.ObjectId,
name : String,
user : { type: Schema.Types.ObjectId, ref: 'User' } // removed [] here too
families : [{ type: Schema.Types.ObjectId, ref: 'Family' }]
});
我已经添加了将Homer添加到Simpson系列的示例示例。希望这可以帮助 :)
addNewFamilyMember: async (_, {personID, familyID}) => {
try{
let family = await Family.findOne({_id: familyID});
let person = await Person.findOne({_id: personID}); // created to push the objectId of the family in this
if (!family){
throw new Error ('Family not found !')
} else {
let updatedFamily = await Family.findByIdAndUpdate(
{ _id: familyID },
{
"$addToSet": { // "addToSet" inserts into array only if it does not exist already
persons: personID
}
},
{ new: true }
);
person.families.push(updatedFamily); // pushing objectId of the Simpson family in Person "Homer"
person = await person.save();
updatedFamily.persons.push(person); // pushing "Homer" in the Simpson family
updatedFamily = updatedFamily.save();
return updatedFamily;
}
} catch(e){
throw e;
}
}
如果要执行更新,那么它取决于您的目的意图(例如,如果您只想更新名称“Homer”,您只需要在Person集合中更新它,因为Family集合已经引用了Homer的objectId,因此每次对Homer进行更新时,更新的文档都会被Family collection引用!),以及
如果你想执行删除,那么在这种情况下,方法也会根据场景而有所不同,就好像你想删除一个人文档,或者只是从家庭中删除人参考,或者从家庭中删除家庭参考人!!
假设您要删除一个人,那么在这种情况下,您必须接受personId并搜索该人,并且由于您可以通过此人访问这些家庭,您可以通过person.families访问这些家庭并删除personId来自各自的家庭!然后,您也可以删除关联的用户,因为您也可以从同一个人对象中引用该用户。
总而言之,这取决于您对行为的选择,以及您在模式中需要多少清理。如果采用不同的方法,上述过程将会有所不同。