by Andrew Akagawa
I recently hit a wall trying to create a review service for our new website healthrate using Mongoose. For anyone who has used Mongoose to the point of arrays within arrays within arrays, you may reach a point where you miss the good old days of SQL based programming. In my googling and continued learning of Mongoose, I stumbled upon the solution of Schemas referencing Schemas. Unfortunately, I lost a day trying to figure it out, so I thought I would write a quick blog to help others figure it out faster.
My example has a user schema with various information, and a review schema in which others can leave reviews for a user.
Here is an example of a User schema file:
The key thing to notice is the reviews array, which has subdocuments containing an ObjectId type, referencing ‘Reviews’. We will define ‘Reviews’ in the next step. The actual review data that will be populated here will just be an array of ObjectIds that reference reviews from our separate review schema.
Hooray! No longer does this have to be an array nestled in my user schema! Here is an example of my review schema:
You can now see in our mongoose model where ‘Reviews’ ties to the User reviews reference in Step 1. The ObjectIds created for each review will be referenced by the User schema.
Be sure to reference both your user and review schema files if called in separate files. Mine are saved in the models directory and referenced as shown:
So, say you have a new set of review data. Below we have it defined in a review variable. We also know the ObjectId for the user being updated and have it defined as mySpecifiedUserId. Here is my code to save and return the data:
If you are familiar with Mongoose, then you should recognize most of this. Above, we are saving the review to the Reviews schema, and pushing only the review ObjectId to the reviews array of the User schema. The returned data array will contain all of the User data in the document as well as the associated nested data in the reviews array.
The one important thing to note is that you need to use populate to actually return the data in the review array, otherwise it will just return the ObjectIds for the reviews.
On a final note, why this helps? As of the time I am writing this, Mongoose doesn’t really support doing any kind of operations or modifications to arrays within schemas. So, if I simply defined my reviews array within the User schema, it would be difficult to find and modify a single review. But with a nested schema and a MEAN stack, you can easily pull an array of reviews for a particular User, and then reference the ObjectId for each review to modify the Reviews schema directly.
Hope this helps!
If so, please like us on any of your favorite social medias and/or Share .