Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mongoose schema within schema

How can I add a schema to another schema? This doesn't seem to be valid:

var UserSchema = new Schema({     name        : String,     app_key     : String,     app_secret  : String })    var TaskSchema = new Schema({     name            : String,     lastPerformed   : Date,     folder          : String,     user            : UserSchema }) 

I checked the website and it shows how to declare it for an array but not for single.

Thanks

like image 378
0xSina Avatar asked Jan 05 '12 03:01

0xSina


People also ask

Can you have a schema within a schema?

Schemas can be nested to represent relationships between objects (e.g. foreign key relationships). For example, a Blog may have an author represented by a User object. Use a Nested field to represent the relationship, passing in a nested schema.

How do I create a schema inside a schema in MongoDB?

To get this, you could do the following: var UserSchema = new Schema({ name : String, app_key : String, app_secret : String, tasks : [{type: Schema. ObjectId, ref: 'Task'}] // assuming you name your model Task }); var TaskSchema = new Schema({ name : String, lastPerformed : Date, folder : String, user : {type: Schema.

Which schema types are not supported by Mongoose?

Mongoose does not natively support long and double datatypes for example, although MongoDB does. However, Mongoose can be extended using plugins to support these other types.


1 Answers

There are a few ways to do this. The simplest is just this:

var TaskSchema = new Schema({     name            : String,     lastPerformed   : Date,     folder          : String,     user            : Schema.ObjectId }); 

Then you just have to make sure your app is writing that id and using it in queries to fetch "related" data as necessary.

This is fine when searching tasks by user id, but more cumbersome when querying the user by task id:

// Get tasks with user id Task.find({user: user_id}, function(err, tasks) {...});  // Get user from task id Task.findById(id, function(err, task) {   User.findById(task.user, function(err, user) {     // do stuff with user   } } 

Another way is to take advantage of Mongoose's populate feature to simplify your queries. To get this, you could do the following:

var UserSchema = new Schema({     name        : String,     app_key     : String,     app_secret  : String,     tasks       : [{type: Schema.ObjectId, ref: 'Task'}] // assuming you name your model Task });  var TaskSchema = new Schema({     name            : String,     lastPerformed   : Date,     folder          : String,     user            : {type: Schema.ObjectId, ref: 'User'} // assuming you name your model User }); 

With this, your query for all users, including arrays of their tasks might be:

User.find({}).populate('tasks').run(function(err, users) {   // do something }); 

Of course, this means maintaining the ids in both places. If that bothers you, it may be best to stick to the first method and just get used to writing more complex (but still simple enough) queries.

like image 144
glortho Avatar answered Oct 05 '22 11:10

glortho