Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to retrieve a specific field from a subdocument array with mongoose

I'm trying to get a specific field from a subdocument array

I'm not gonna include any of the fields in the parent doc

Here is the sample document

{
    "_id" : ObjectId("5409dd36b71997726532012d"),
    "hierarchies" : [ 
        {
            "rank" : 1,
            "_id" : ObjectId("5409df85b719977265320137"),
            "name" : "CTO",
            "userId" : [ 
                ObjectId("53a47a639c52c9d83a2d71db")
            ]
        }
    ]
}

I would like to return the rank of the hierarchy if the a userId is in the userId array

here's what I have so far in my query

collectionName.find({{hierarchies:
   {$elemMatch : {userId: ObjectId("53a47a639c52c9d83a2d71db")}}}
    , "hierarchies.$.rank", function(err,data){}

so far it returns the entire object in the hierarchies array I want, but I would like to limit it to just the rank property of the object.

like image 513
Austin Davis Avatar asked Sep 05 '14 16:09

Austin Davis


1 Answers

The projection available to .find() queries generally in MongoDB does not do this sort of projection for internal elements of an array. All you can generally do is return the "matched" element of the array entirely.

For what you want, you use the aggregation framework instead, which gives you more control over matching and projection:

Model.aggregate([
    { "$match": {
        "hierarchies.userId": ObjectId("53a47a639c52c9d83a2d71db")
    }},
    { "$unwind": "$hierarchies" },
    { "$match": {
        "hierarchies.userId": ObjectId("53a47a639c52c9d83a2d71db")
    }},
    { "$project": {
        "rank": "$hierarchies.rank"
    }}
],function(err,result) {

})

That basically matches the documents, filters the array content of the document to just the match and then projects only the required field.

like image 142
Neil Lunn Avatar answered Nov 15 '22 05:11

Neil Lunn