猫鼬多对多关系
Mongoose Many to many relations
我是 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);
我不知道我的架构是否正确,我的 userSchema
中是否需要参数 person
?因为信息会重复,所以在 userSchema
中我将拥有 personID,而在 personSchema
中这将是用户 ID。
如果我理解为我的请求提供此重复值有用吗?但是如果信息重复,我需要执行两个查询来更新两个表?
例如,如果我有一个有家庭的人(personSchema 中的 families 参数),并且在这个家庭中我有这个人(familySchema 中的 persons 参数)。删除/更新表中行的请求是什么?
谢谢
恕我直言,如果满足您的需求,您的架构似乎不错!! (不过,如果您认为您当前的模式可以满足您的目的而不会臃肿,那么它很好)..
- "Person" 似乎是唯一类型的用户和要连接到其他实体的实体。只要是这种情况,您就可以随意从 userschema 中删除 person 参数,因为您可以从 person 访问用户信息。但是让我们假设如果存在另一个实体 "Aliens" 也有自己独特的家庭,那么最好在 "User" 模式中添加 alien 和 person 参数以查看用户类型。(如只要只有一种类型,即 Person,那么您可能不需要在 userschema 中添加它)。以防万一,如果您仍然想保留它,那么请在传递数组时在您的架构中进行以下更改,尽管它似乎是一对一的关系!
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' }]
});
是的,如果要保持一致性,您需要为实体 Person 和 Family 更新它。但是,它可以在一个请求/突变中完成。
好吧,您可以根据业务逻辑的流程顺序执行请求。假设 "Homer" 是一个 Person,他是 Simpson Family 的新成员。
因此,在这种情况下,您可以将 "Homer" 添加到 Family 集合 (table) 中,然后将
此 Simpson(家庭集合)的 ObjectId 到 Person 实体。
我在下面添加了将荷马添加到辛普森一家的示例。希望这有帮助:)
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 集合引用!),并且
如果你想执行删除,那么在这种情况下,方法也会根据场景而有所不同,就像你想删除一个人文档,或者只是从家庭中删除这个人的引用,或者删除来自此人的家庭推荐!!
假设你想删除一个人,那么在这种情况下,你必须获取 personId 并搜索那个人,因为你可以通过这个人访问家庭,你可以通过 person.families 并从各自的家庭中删除 personId !然后您也可以删除关联的用户,因为您也从同一个人对象中引用了该用户。
总而言之,这取决于您选择的操作,以及您希望在架构中进行多少清理。如果我们采用不同的方法,上述过程将有所不同。
我是 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);
我不知道我的架构是否正确,我的 userSchema
中是否需要参数 person
?因为信息会重复,所以在 userSchema
中我将拥有 personID,而在 personSchema
中这将是用户 ID。
如果我理解为我的请求提供此重复值有用吗?但是如果信息重复,我需要执行两个查询来更新两个表?
例如,如果我有一个有家庭的人(personSchema 中的 families 参数),并且在这个家庭中我有这个人(familySchema 中的 persons 参数)。删除/更新表中行的请求是什么?
谢谢
恕我直言,如果满足您的需求,您的架构似乎不错!! (不过,如果您认为您当前的模式可以满足您的目的而不会臃肿,那么它很好)..
- "Person" 似乎是唯一类型的用户和要连接到其他实体的实体。只要是这种情况,您就可以随意从 userschema 中删除 person 参数,因为您可以从 person 访问用户信息。但是让我们假设如果存在另一个实体 "Aliens" 也有自己独特的家庭,那么最好在 "User" 模式中添加 alien 和 person 参数以查看用户类型。(如只要只有一种类型,即 Person,那么您可能不需要在 userschema 中添加它)。以防万一,如果您仍然想保留它,那么请在传递数组时在您的架构中进行以下更改,尽管它似乎是一对一的关系!
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' }]
});
是的,如果要保持一致性,您需要为实体 Person 和 Family 更新它。但是,它可以在一个请求/突变中完成。
好吧,您可以根据业务逻辑的流程顺序执行请求。假设 "Homer" 是一个 Person,他是 Simpson Family 的新成员。 因此,在这种情况下,您可以将 "Homer" 添加到 Family 集合 (table) 中,然后将 此 Simpson(家庭集合)的 ObjectId 到 Person 实体。
我在下面添加了将荷马添加到辛普森一家的示例。希望这有帮助:)
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 集合引用!),并且
如果你想执行删除,那么在这种情况下,方法也会根据场景而有所不同,就像你想删除一个人文档,或者只是从家庭中删除这个人的引用,或者删除来自此人的家庭推荐!!
假设你想删除一个人,那么在这种情况下,你必须获取 personId 并搜索那个人,因为你可以通过这个人访问家庭,你可以通过 person.families 并从各自的家庭中删除 personId !然后您也可以删除关联的用户,因为您也从同一个人对象中引用了该用户。
总而言之,这取决于您选择的操作,以及您希望在架构中进行多少清理。如果我们采用不同的方法,上述过程将有所不同。