The correct way to store a one-to-one document link in MongoDB

I have two MongoDB collections of user and customer , which are in a one-to-one relationship. I'm new to MongoDB, and I'm trying to insert documents manually, although I have Mongoose installed. I'm not sure if this is the correct way to store a document link in MongoDB.

I am using a normalized data model, and here is my snapshot of the Mongoose schema for customer :

 /** Parent user object */ user: { type: Schema.Types.ObjectId, ref: "User", required: true } 

user

 { "_id" : ObjectId("547d5c1b1e42bd0423a75781"), "name" : "john", "email" : " test@localhost.com ", "phone" : "01022223333", } 

I want to make a link to this user document from a customer document. Which of the following is true: (A) or (B)?

customer (A)

 { "_id" : ObjectId("547d916a660729dd531f145d"), "birthday" : "1983-06-28", "zipcode" : "12345", "address" : "1, Main Street", "user" : ObjectId("547d5c1b1e42bd0423a75781") } 

customer (B)

 { "_id" : ObjectId("547d916a660729dd531f145d"), "birthday" : "1983-06-28", "zipcode" : "12345", "address" : "1, Main Street", "user" : { "_id" : ObjectId("547d5c1b1e42bd0423a75781") } } 
+5
source share
4 answers

Use option A. If you do not want to denormalize any other data (for example, username), there is no need to create a child object.

It also avoids unexpected complications with the index, since indexing an object may not behave as you expect.

Even if you were to embed an object, _id would be a strange name - _id is only a reserved name for a first class database document.

+2
source

Remember these things

An attachment is better for ...

  • Small attachments
  • Data that does not change regularly
  • When acceptable consistency is acceptable
  • Documents that grow on a small amount
  • Data that you often need to complete the second request for fast readings

Links are better for ...

  • Large attached documents
  • Volatile data
  • If immediate coordination is required
  • Documents that grow in large numbers
  • Data that you often exclude from results
  • Quick record

Option A is better. you can also use populate with mongoose

+2
source

In mongodb it is highly recommended to embed the document as much as possible, especially in your case when you have a 1 to 1 relationship.

Why? you cannot use Atom-join-operations (even this is not your main problem) in your requests (not the main reason). But the best reason is every association (theoretically) that requires a hard search, which takes about 20 ms. only one distortion is required to embed your sub-document.

I believe that the best db scheme for you uses only an identifier for all of your entities.

 { _id : ObjectId("547d5c1b1e42bd0423a75781"), userInfo : { "name" : "john", "email" : " test@localhost.com ", "phone" : "01022223333", }, customerInfo : { "birthday" : "1983-06-28", "zipcode" : "12345", "address" : "1, Main Street", }, staffInfo : { ........ } } 

Now, if you just want userinfo , you can use

 db.users.findOne({_id : ObjectId("547d5c1b1e42bd0423a75781")},{userInfo : 1}).userInfo; 

it will only give you userInfo :

 /* 0 */ { "name" : "john", "email" : " test@localhost.com ", "phone" : "01022223333" } 

And if you just want to use ** customerInfo **, you can use

 db.users.findOne({_id : ObjectId("547d5c1b1e42bd0423a75781")},{customerInfo : 1}).customerInfo; 

it will only give you customerInfo :

 /* 0 */ { "birthday" : "1983-06-28", "zipcode" : "12345", "address" : "1, Main Street" } 

etc.

This circuit has a minimal difficult circuit and in fact you are using the mongodb document-based function with the maximum performance you can achieve.

+1
source

One to one relationship

1 to 1 relationships are relationships where each element corresponds to exactly one other element. eg:.

  • the employee has a resume and vice versa
  • building and floor plan and vice versa
  • the patient has a medical history and vice versa

     //employee { _id : '25', name: 'john doe', resume: 30 } //resume { _id : '30', jobs: [....], education: [...], employee: 25 }
    //employee { _id : '25', name: 'john doe', resume: 30 } //resume { _id : '30', jobs: [....], education: [...], employee: 25 } 

We can model the relationship between employees and resumes, having a collection of employees and a collection of resumes, and the employee points to the resume through a link where we have an ID that corresponds to the ID in the resume collection. Or, if we prefer, we can refer in another direction, where we have the employee key inside the resume collection, and it can point to the employee himself. Or, if we want, we can embed. Thus, we could take the entire resume document, and we could embed it directly into the collection of employees or vice versa.

This attachment depends on how data accesses the application and how often it is accessed. We need to consider:

  • access frequency
  • the size of objects is that which grows all the time and that does not grow. Therefore, every time we add something to the document, there is a point beyond which the document should be moved to the collection. If the document is larger than 16 MB , this is unlikely in most cases.
  • atomicity of data - there are no transactions in MongoDB , there are separate operations on individual documents. Therefore, if we knew that we would not be able to confront any inconsistency and that we want to constantly update the entire employee plus a resume, we can decide to put them in the same document and insert them anyway so that we can update it all right away.
+1
source

Source: https://habr.com/ru/post/1208131/


All Articles