Last Updated: August 09, 2016
·
80.93K
· dominikgarber

Querying sub-documents and sub-sub-documents in Mongoose

FInding sub-docs in mongoose the first time may seem a bit hard or just confusing. That's why I decided to write this.

Creating the Schemas

var likesSchema = new Schema({
    username: 'string'
})
var statusSchema = new Schema({
    text: 'string',
    likes: [likesSchema]
})
var userSchema = new Schema({
    username: 'string',
    status: [statusSchema]
})                                                                                

As you can see we embedded the likesSchema inside the statusSchema which is embedded inside the userSchema. The problem with sub-docs is that they are not saved individually, they are saved there the parent Schema is saved, so if you need to use the sub-docs individually this may not be the right approach for you.

Creating some users, sub-docs and sub-sub-docs

var User = mongoose.model('User', userSchema);

var user = new User({
    username: 'derp',
    status: [{text: 'Hello world!'}]
})

var friend = new User({
    username: 'goku',
    status: [{text: 'Kamehameha!!!'}]
})
user.save(callback);
friend.save(callback);

This will create two users. After this comes the interesting part: Querying the sub-docs, creating them and modifying them. As well with the sub-sub-docs

Querying

//If you know the sub-doc position in the array it is pretty simple to query it

var subdoc = user.status[0];
console.log(subdoc.text); //This will output: Hello world!

//If you know its id it is also really simple
var subdoc = user.status.id(id); //where id is the sub-doc _id

/*
    If you only know the text it is a little bit more complicated
*/

User.findOne({'status.text': 'Kamehameha!!!'}, function(err, the_user){
    if(err)console.log(err)
    if(the_user){
        console.log(the_user.username); //goku
    }
})

Adding sub-sub-docs

subdoc.likes.push({
    username: friend.username
})

subdoc.save(callback);

//It is really easy as pie!

Query sub-sub-docs

This is were trouble comes, because there is not really a way in mongoose to query them. You can use the position in the array if you know it, but you can't really keep track of this.

Remember it is an array so you can do this to query them:

for(i in subdoc.likes){
    //username is the variable of the username of the like you want to find
    if(likes[i].username == username){
        //do something cool here
    }
}

And that's it!

5 Responses
Add your response

How do you go about updating a subdocument given the parent id and the child id?

over 1 year ago ·

You find the parent by his id and then you go:
vat suddoc = Parent.children.id(childrenid);

over 1 year ago ·
if(err) console.log(err);
if(the_user){
    console.log(the_user.username); //goku
  }

yikes.

over 1 year ago ·

I exactly did what has been mentioned, but seems to have an error.

TypeError: Object [object Object],[object Object],[object Object] has no method 'id'

Could you please help me out? Thanks in advance.

over 1 year ago ·

can I see your code or some of it?

over 1 year ago ·

Have a fresh tip? Share with Coderwall community!

Post
Post a tip