Referencing another schema in Mongoose
It sounds like the populate method is what your looking for. First make small change to your post schema:
var postSchema = new Schema({
name: String,
postedBy: {type: mongoose.Schema.Types.ObjectId, ref: 'User'},
dateCreated: Date,
comments: [{body:"string", by: mongoose.Schema.Types.ObjectId}],
});
Then make your model:
var Post = mongoose.model('Post', postSchema);
Then, when you make your query, you can populate references like this:
Post.findOne({_id: 123})
.populate('postedBy')
.exec(function(err, post) {
// do stuff with post
});
How to reference another schema in my Mongoose schema?
You can do so by using Population
Population is the process of automatically replacing the specified
paths in the document with document(s) from other collection(s). We
may populate a single document, multiple documents, plain object,
multiple plain objects, or all objects returned from a query.
Suppose your Event Schema is defined as follows:
var mongoose = require('mongoose')
, Schema = mongoose.Schema
var eventSchema = Schema({
title : String,
location : String,
startDate : Date,
endDate : Date
});
var personSchema = Schema({
firstname: String,
lastname: String,
email: String,
gender: {type: String, enum: ["Male", "Female"]}
dob: Date,
city: String,
interests: [interestsSchema],
eventsAttended: [{ type: Schema.Types.ObjectId, ref: 'Event' }]
});
var Event = mongoose.model('Event', eventSchema);
var Person = mongoose.model('Person', personSchema);
To show how populate is used, first create a person object,
aaron = new Person({firstname: 'Aaron'})
and an event object,
event1 = new Event({title: 'Hackathon', location: 'foo'})
:
aaron.eventsAttended.push(event1);
aaron.save(callback);
Then, when you make your query, you can populate references like this:
Person
.findOne({ firstname: 'Aaron' })
.populate('eventsAttended') // only works if we pushed refs to person.eventsAttended
.exec(function(err, person) {
if (err) return handleError(err);
console.log(person);
});
How can i reference a field in another mongoose model so i can retrieve multiple documents from different collections
You will need to reference mongoose model in your schema, instead of schema.
Like:
Subcategory schema
const SubcategorySchema = mongoose.Schema({
category_id: {
type: String, required: true
},
name: {
type: String, required: true
},
status: {
type: Number, default: 0
},
icon: {
type: String, required: false
},
created : {
type : Date,
default: Date.now()
}
});
const SubCategoryModel = mongoose.model('SubCategory', SubcategorySchema);
CategorySchema
const subcategories = require('./Subcategory')
const CategorySchema = mongoose.Schema({
name: {
type: String, required: true
},
icon: {
type: String, required: false
},
status: {
type: Number, default: 0
},
created : {
type : Date,
default: Date.now()
},
subcategories: {
type: mongoose.Schema.Types.ObjectId,
ref: "SubCategory" // this name should be same as the model name specified while declaring model
}
});
Types for referencing another schema in mongoose
Yes, it is possible to use types other than ObjectId
for ref
s, but Mongoose recommends using ObjectId
s unless you have a good reason to do otherwise.
From the documentation for Populate:
Note:
ObjectId
,Number
,String
, andBuffer
are valid for use as refs. However, you should useObjectId
unless you are an advanced user and have a good reason for doing so.
Mongoose: Reference schema in properties or add as an array? which is better
You should have a reference to the user in the PostSchema
.
This is the better approach because a user can have multiple posts and if you save the posts in the UserSchema
as an array, that array can grow infinitely. This can cause problems because there's a limit on the max size of a mongodb document. Single mongodb document cannot be greater than 16Mb.
Saving Posts in the User schema is better from the performance perspective but considering the limit on the size of mongodb document and the fact that a user can have many posts, a child document (Post) referencing its parent document (User) is the better approach here.
How do I reference another field in mongoDB Schema instead of ObjectID?
You can use mongoose's populate to to this:
Book.
findOne({ ... }).
populate('author').
exec(function (err, book) {
if (err) return handleError(err);
// book.author will now be populated
});
Then, in react you can access the name property on the author
object:
function Book(book){
const {title}, {pages}, {descritpion}, {author} = book;
return (
<h1> {title} <h1>
<p>{pages} , {description}<p>
<p>{author.name}<p>
);
}
Related Topics
Javascript: How to Pass Object by Value
Finding Element's Position Relative to the Document
Sanitizing User Input Before Adding It to the Dom in JavaScript
Angular 2: Import External Js File into Component
Using Jquery to Find an Element at a Particular Position
Plain Count Up Timer in JavaScript
Jquery Dom Changes Not Appearing in View Source
How to Do Two-Way Filtering in Angularjs
Using Multiple Mongodb Databases with Meteor.Js
Generate HTML Table from 2D JavaScript Array
Convert Time Interval Given in Seconds into More Human Readable Form
Retrieving Binary File Content Using JavaScript, Base64 Encode It and Reverse-Decode It Using Python
Getting Key with the Highest Value from Object