39

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 Answers 2

79

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.

Sign up to request clarification or add additional context in comments.

8 Comments

why the returned parameter is foundLinks and not foundUsers ?
Could you answer to @geevee comment ?
@RémiBecheras @geevee It should be foundUsers, but i just used the code the OP had originally posted.. it was foundLinks there.. you can check that :)
Thank you. We asked because if it was right, we missed something big.... I just edited your post to fixing it
Thanks for this answer but those queries returns Users and not only Link as asked by @vlad. Is there a way to retreive only Links ?
|
3

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){
      // ---
   });

2 Comments

What is the { 'links.$' : 1 } part called? I'm looking for the documentation on this feature. I'm assuming it's saying to just return the one nested document?
Adding to this, const foundLinks = foundUsers.links[0]

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.