Chinmay Waghmare
Chinmay Waghmare

Reputation: 5456

Get only subdocument array by field

I have the following ServiceProvider collection.

{
    "_id" : ObjectId("5724a838588aeca6158b4567"),
    "ServiceProviderID" : 3,
    "Title" : "test1",
    "PostedMessage" : "test1",
    "TotalComments" : 0,
    "TotalShares" : 0,
    "TotalThanks" : 0,
    "AddedOn" : "2016-04-30",
    "LastModifiedOn" : "2016-04-30 12:42:32",
    "PostAttachment" : {
        "ImagePath" : ""
    },
    "PostCommentUserIDs" : [
        "3"
    ],
    "PostComments" : [
        { // Only want this array to return
            "ID" : "1462020155845421948",
            "UserID" : 3,
            "CommentMessage" : "1",
            "TotalThanks" : 0,
            "AddedOn" : "2016-04-30 12:42:35",
            "LastModifiedOn" : "2016-04-30 12:42:35",
            "CommentAttachment" : {
                "ImagePath" : ""
            }
        },
        {
            "ID" : "14620201551142120893",
            "UserID" : 3,
            "CommentMessage" : "2",
            "TotalThanks" : 0,
            "AddedOn" : "2016-04-30 12:42:35",
            "LastModifiedOn" : "2016-04-30 12:42:35",
            "CommentAttachment" : {
                "ImagePath" : ""
            }
        },
        {
            "ID" : "14620201561666853653",
            "UserID" : 3,
            "CommentMessage" : "3",
            "TotalThanks" : 0,
            "AddedOn" : "2016-04-30 12:42:36",
            "LastModifiedOn" : "2016-04-30 12:42:36",
            "CommentAttachment" : {
                "ImagePath" : ""
            }
        }
    ],
    "Subscriber" : [ ]
}

How to get only PostComments subdocument array by ID field.

I have tried the following query:

db.ServiceProvider.find({
    "_id" : ObjectId('5724a838588aeca6158b4567'),
    "PostComments.ID":"1462020155845421948"
},{
    "_id": 0,
    "PostComments" :{
       "$elemMatch":{
           "PostComments.ID" : "1462020155845421948"
       } 
    }
}) 

But it is not working. Can anyone please help. Thanks!

Edit:

I want only the following PostComments subdocument array to be returned:

{ 
     "ID" : "1462020155845421948",
     "UserID" : 3,
     "CommentMessage" : "1",
     "TotalThanks" : 0,
     "AddedOn" : "2016-04-30 12:42:35",
     "LastModifiedOn" : "2016-04-30 12:42:35",
     "CommentAttachment" : {
          "ImagePath" : ""
     }
},

Upvotes: 1

Views: 476

Answers (1)

Rolson Quadras
Rolson Quadras

Reputation: 446

The query that you have posted doesn't written any document since you are adding "PostComments.ID" filter inside $elemMatch projection. It should just be ID.

db.ServiceProvider.find({
    "_id" : ObjectId('5724a838588aeca6158b4567'),
    "PostComments.ID":"1462020155845421948"
},{
    "_id": 0,
    "PostComments" :{
       "$elemMatch":{
           "ID" : "1462020155845421948"
       } 
    }
}) 

You can use below aggregate function to re-shape the array elements to get it at first level (to get the expected result).

db.ServiceProvider.aggregate([
    {$match : {"_id" : ObjectId('5724a838588aeca6158b4567')}},
    {$unwind : "$PostComments"},
    {$match : {"PostComments.ID":"1462020155845421948"}},
    {$project : { "_id" : 0, "ID" : "$PostComments.ID", "UserID" : "$PostComments.UserID", "CommentMessage" : "$PostComments.CommentMessage","TotalThanks" : "$PostComments.TotalThanks","CommentAttachment" : "$CommentAttachment.UserID",}}
])

This aggregate function will print below result.

{  
   "TotalThanks":0,
   "ID":"1462020155845421948",
   "UserID":3,
   "CommentMessage":"1"
}

Upvotes: 1

Related Questions