37
votes

I am starting out with mongodb and having hard time trying to query nested documents. I have two schemas:

var LinkSchema = new mongoose.Schema({
    url: String,
    name: String
});

var UserSchema = new mongoose.Schema({
    name: String,
    links: [LinkSchema]
});

As you can see, I am just tying to build a simple bookmarking tool. Each user has a name and a collection of links. Each link has a name and a url.

Now, what I am trying to do is for example, see if a link already exists in someone's links array. I would like to be able to do something like this (Trying to get vlad's link collection and then see if the query link already belongs to the collection or not):

app.get("/:query", function(req, res){
  User.findOne({"name":"vlad"}, function(err, user){
    user.links.find({"url":req.params.query}, function(err, foundLinks){
      if(foundLinks){
        res.send("link already exists!");
      } else {
        res.send("link doesn't exist!");
      }
    });
  });
});

Of course, this code doesn't work, because apparently I can't do a "user.links.find()". I guess I can just do a user.links.map to extract only urls and then run a membership query against it. But I think this would be far from the right solution. There's gotta be a way to do something like this natively using DB queries. Can someone help? Thank you!

2

2 Answers

75
votes

You can query an embedded document in mongoose like this

   User.find({'links.url':req.params.query}, function(err, foundUsers){
      // ---
   });

and to find the links that belong to the user "vlad", you can write

   User.find({name:'vlad','links.url':req.params.query}, function(err, foundUsers){
      // ---
   });

This will do the trick.

2
votes

To find a specific link that belongs to a specific user you can do this

User.find({name:'vlad','links.url':req.params.query}, { 'links.$': 1 },  function(err, foundUsers){
      // ---
   });