Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get one element from an array of objects that's part of one document (mongoose)

I have a schema which contains Friends . Friends is an array where each element is an object that contains an id, gender, and emoji.

var userSchema = new Schema({
    id: {
        type: String,
        unique: true,
        required: true
    },
    gender: String,

    Friends: [{
        id: String
        gender: String
        emoji: String

    }]

});

In the code below, I'm accessing one document which contains a Friends array and specifying that search with distinct such it only shows the document's array of Friends. I need to access only one element of that array that contains a specified id. Instead of filtering that array after the query like what's done in the code, is there a way to just get the element purely from the query? In other words, is there an extra functionality to distinct or some kind of mongoose operator that allows that?

User.findOne().distinct('Friends', { id: req.body.myId }).then(function(myDoc) {

    var friendAtt = myDoc.filter(function(obj) {
        return obj.id == req.body.id
    })[0]

})
like image 767
Ryan Avatar asked Dec 28 '16 00:12

Ryan


2 Answers

Thanks to bertrand I was able to find that the answer lies in 'Projection'. In mongodb it's '$', in mongoose its select. Here is how I made it work:

User.findOne({id: req.body.myId}).select({ Friends: {$elemMatch: {id: req.body.id}}}),

It only returns the element that matched the id specified in friends.

like image 131
Ryan Avatar answered Oct 20 '22 04:10

Ryan


You don't really need distinct here, you can use find() on Friends.id and filter the first subdocument that match Friends.id with the positional parameter $ :

db.user.find(
    { 'id': 'id1', 'Friends.id': 'id2'},
    { 'Friends.$': 1 }
)

In mongoose :

User.find({ 'id': req.body.myId, 'Friends.id': req.body.id }, { 'Friends.$': 1 }).then(function(myDoc) {
    console.log("_id   :" + myDoc[0].Friends[0].id);
    console.log("gender:" + myDoc[0].Friends[0].gender);
})
like image 37
Bertrand Martel Avatar answered Oct 20 '22 04:10

Bertrand Martel