Jake Stokes
Jake Stokes

Reputation: 466

MongoDB query, project nested docs?

I was wondering if this is possible, or do I need to use the aggregation pipeline instead?

I have read posts such as this, and intuitively feel like it's possible.

Example of docs:

{
    "_id": ObjectID("5143ddf3bcf1bfab37d9c6f"),
    "permalink": "btxcacmbqkxbpgtpeero",
    "author": "machine",
    "title": "Declaration of Independence",
    "tags": [
            "study",
            "law"
    ],
    "comments": [
                  {
                    "body": "comment 1",
                    "email": "[email protected]",
                    "author": "machine_1"
                   },
                  {
                    "body": "comment 2",
                    "email": "[email protected]",
                    "author": "machine_2"
                   },
                  {
                    "body": "comment 3",
                    "email": "[email protected]",
                    "author": "machine_3"
                   },
    ]
    "date": ISODate("2013-03-16T02:50:27.878Z")
}

I am trying to access a particular comment in "comments" by it's index position using dot notation in the projection field, with the following:

db.collection.find({permalink: "btxcacmbqkxbpgtpeero"}, {'comments.0.1.': 1})

Where comments.0 is the first item in the field: the array, and .1 is the second comment in the array.

The result I am getting:

{ "_id" : ObjectID("5143ddf3bcf1bfab37d9c6f"), "comments" : [ {  }, {  }, {  } ] }

If I take away the .1, leaving just comments.0, I get the same result:

{ "_id" : ObjectID("5143ddf3bcf1bfab37d9c6f"), "comments" : [ {  }, {  }, {  } ] }

If I take away the .0, leaving just comments, I get the comments still inside their array:

[
   {
    "body": "comment 1",
    "email": "[email protected]",
    "author": "machine_1"
   },
   {
     "body": "comment 2",
     "email": "[email protected]",
     "author": "machine_2"
   },
   {
     "body": "comment 3",
     "email": "[email protected]",
     "author": "machine_3"
   }
]

Can this be done? If so, how?

Upvotes: 3

Views: 1909

Answers (1)

felix
felix

Reputation: 9285

without aggregation:

db.collection.find({
   permalink:"btxcacmbqkxbpgtpeero"
},
{
   comments:{
      $slice:[
         0,
         1
      ]
   }
})

returns

{
   "_id":ObjectId("583af24824168f5cc566e1e9"),
   "permalink":"btxcacmbqkxbpgtpeero",
   "author":"machine",
   "title":"Declaration of Independence",
   "tags":[
      "study",
      "law"
   ],
   "comments":[
      {
         "body":"comment 1",
         "email":"[email protected]",
         "author":"machine_1"
      }
   ]
}

try it online: mongoplayground.net/p/LGbVWPyVkFk

with aggregation:

db.collection.aggregate([
   {
      $match:{
         permalink:"btxcacmbqkxbpgtpeero"
      }
   },
   {
      $project:{
         comment:{
            $arrayElemAt:[
               "$comments",
               0
            ]
         }
      }
   }
])

returns

{
   "_id":ObjectId("583af24824168f5cc566e1e9"),
   "comment":{
      "body":"comment 1",
      "email":"[email protected]",
      "author":"machine_1"
   }
}

Upvotes: 3

Related Questions