![](https://rxharun.com/wp-content/uploads/2024/02/referencing-another-schema-in-mongoose_305467-1.png)
In this next example, I am going to create two new schemas that will demonstrate how to create a relationship to another schema: author and book. The book schema will contain a reference to the author schema.
Author.js
var authorSchema = mongoose.Schema({
_id: mongoose.Schema.Types.ObjectId,
name: {
firstName: String,
lastName: String
},
biography: String,
twitter: String,
facebook: String,
linkedin: String,
profilePicture: Buffer,
created: {
type: Date,
default: Date.now
}
});
var Author = mongoose.model("Author", authorSchema);
Above is the author schema that expands upon the concepts of the user schema that I created in the previous example. To link the Author and Book together, the first property of the author schema is an _id property that is an ObjectId schema type. _id is the common syntax for creating a primary key in Mongoose and MongoDB. Then, like the user schema, I’ve defined a name property containing the author’s first and last name.
Expanding upon the user schema, the author contains several other String schema types. I’ve also added a Buffer schema type that could hold the author’s profile picture. The final property holds the created date of the author; however, you may notice it is created slightly differently because it has defined a default value of “now”. When an author is persisted to the database, this property will be set to the current date/time.
Now let’s create a book schema that contains a reference to the author by using the ObjectId schema type:
Book.js
var bookSchema = mongoose.Schema({
_id: mongoose.Schema.Types.ObjectId,
title: String,
summary: String,
isbn: String,
thumbnail: Buffer,
author: {
type: mongoose.Schema.Types.ObjectId,
ref: "Author"
},
ratings: [
{
summary: String,
detail: String,
numberOfStars: Number,
created: {
type: Date,
default: Date.now
}
}
],
created: {
type: Date,
default: Date.now
}
});
var Book = mongoose.model("Book", bookSchema);
Now save some objects in this model
var jamieAuthor = new Author {
_id: new mongoose.Types.ObjectId(),
name: {
firstName: 'Jamie',
lastName: 'Munro'
},
biography: 'Jamie is the author of ASP.NET MVC 5 with Bootstrap and Knockout.js.',
twitter: 'https://twitter.com/endyourif',
facebook: 'https://www.facebook.com/End-Your-If-194251957252562/'
};
jamieAuthor.save(function(err) {
if (err) throw err;
console.log('Author successfully saved.');
var mvcBook = new Book {
_id: new mongoose.Types.ObjectId(),
title: 'ASP.NET MVC 5 with Bootstrap and Knockout.js',
author: jamieAuthor._id,
ratings:[{
summary: 'Great read'
}]
};
mvcBook.save(function(err) {
if (err) throw err;
console.log('Book successfully saved.');
});
var knockoutBook = new Book {
_id: new mongoose.Types.ObjectId(),
title: 'Knockout.js: Building Dynamic Client-Side Web Applications',
author: jamieAuthor._id
};
knockoutBook.save(function(err) {
if (err) throw err;
console.log('Book successfully saved.');
});
});
The example starts by creating and saving a jamieObject that is created from anAuthor Model. Inside the save function of the jamieObject, if an error occurs, the application will output an exception. When the save is successful, inside the save function, the two book objects are created and saved. Similar to the jamieObject, if an error occurs when saving, an error is outputted; otherwise, a success message is outputted in the console.
To create the reference to the Author, both of the book objects reference the author schema’s _id primary key in the author property of the book schema.
The ObjectId
data type specifies a link to another document in your database. For example, if you had a collection of books and authors, the book document might contain an ObjectId property that refers to the specific author of the document.
1> https://scotch.io/@ossaijad/how-to-do-join-operations-and-create-links-between-mongodb-collection
Take an example of a social-network https://github.com/PrinceDavis/mongodb-joins. The repo contains a working webservice that allow you to create users, posts, and comments. You can also fetch users, their friends, posts, post creators and comments.
Here’s my user model – src/models/user/user.js
const Schema = new mongoose.Schema({
fullname: {
type: String,
required: true
},
username: {
type: String,
required: true
},
friends: [
{
type: mongoose.Schema.ObjectId,
ref: "User"
}
]
});
module.exports = mongoose.model("User", Schema);
user
model to create a reference to the ‘friends’ property – I am doing mongoose.Schema.ObjectId
. And this ObjectId’s will reference the user
schema’s _id primary key. This is because by default mongodb assigns the _id field to take mongoose.Schema.Types.ObjectId
– even though I dont set it to be so explicitly. [See the other file “referencing-another-schema-in-Mongoose-1.md ]
Inside the above Here I created a mongoose schema for user data, notice that the type of friends is itself a type of ObjectId and has a ref property, this is how mongoose perform collection linking or join or relationships. Each user would have a friends array which would hold id values of other friends that they are friends with. back in the all method in our controller where we call populate function on UserModel we are telling mongoose to swap the id values for the real collection that those values represent.
And then in my src/models/post/post.js
A post has comment and a user who created it. That is, a Post belong to a User, hence it’s ‘creator’ property will have its ref to User
const Schema = new mongoose.Schema({
creator: { type: mongoose.Schema.ObjectId, ref: 'User', required: true },
title: { type: String, required: true },
body: { type: String, required: true }
}
module.exports = mongoose.model('Post', Schema)
Post
And this is my comment.js file. A comment belong to a Post, hence the ‘post’ property will have its ref to const Schema = new mongoose.Schema({
post: { type: mongoose.Schema.ObjectId, ref: "Post" },
body: { type: String, required: true }
});
module.exports = mongoose.model("Comment", Schema);
The ref attribute
DBRefs have the following fields:
$ref – The $ref field holds the name of the collection where the referenced document resides.
$id – The $id field contains the value of the _id field in the referenced document.
$db – Optional.
Contains the name of the database where the referenced document resides.
Only some drivers support $db references.
https://docs.mongodb.com/manual/reference/database-references/#dbrefs
More sources to read about
1> https://docs.mongodb.com/manual/reference/database-references/
2>https://code.tutsplus.com/articles/an-introduction-to-mongoose-for-mongodb-and-nodejs–cms-29527