I read the official documentation but still don't get it https://docs.mongodb.com/manual/tutorial/model-embedded-one-to-one-relationships-between-documents/ Explain me pls, how to create in my example. I have nest.js app with mongoose. Two schemas (2 tables in db):
1)
export type UserModelDocument = UserModel & Document;
@Schema()
export class UserModel {
@Prop()
email: string;
@Prop({ type: MongooseSchema.Types.ObjectId, ref: 'InviteModel' })
invite: InviteModel;
}
export const UserSchema = SchemaFactory.createForClass(UserModel);
@Schema()
export class InviteModel {
@Prop()
status: string;
}
export const InviteSchema = SchemaFactory.createForClass(InviteModel);
And here, in my service i create a user:
async create(createUserDto: CreateUserDto) {
const userExists = await this.userModel.findOne({ email: createUserDto.email });
if (userExists) {
this.logger.error('User already exists');
throw new NotAcceptableException('User already exists');
}
const createdUser = await new this.userModel(createUserDto).save();
//need some operations to save default invite too in the same user
return toCreateUserDto(createdUser);
}
How to add a relation one-to-one when registering for a new user, so that the object of the created user is also added invite object. Example:
{userEmail: "[email protected]",
invite: {
status: 'not_sent',
}
}
Сan i do it in one request? or I need to save in different requests?
const createdUser = await new this.userModel(createUserDto).save();
const createdInvite = await new this.inviteModel(createInviteDto).save(); ?
CodePudding user response:
It is well explained in the documentation , if you have less frequently searched data you can offload it to second collection to reduce the size of the main document and improve read performance , in case you need the less frequent data you will make a second request to the second collection. In general if your document in first collection is not so big and no impact on read performance best is to embed the field in the first collection and avoid too much collections and fetch everything in single call.
- One-to-one example:
collection 1:
{ _id:"useremail" , frequentData: "the data1" }
collection 2:
{ _id:"useremail" , lessFrequentData:"the data2" }
- Embedding option:
collection 1:
{ _id:"usermail" , frequentData: "the Data1" , lessFrequentData:"the Data2" }
P.S. my personal observation: mongoDB wiredTiger storage engine is splitting and storing data to 32KB blocks on storage so documents below that size are considered relatively small and embedding seems to be the best option if there is no other specific requirements ... Document size is important , but in the document model design the prefered is the denormalized data , correct indexes creation and utilisation will help more with the performance improvement.