Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Project an array with MongoDB

I'm using MongoDB's aggregation pipeline, to get my documents in the form that I want. As the last step of aggregation, I use $project to put the documents into their final form.

But I'm having trouble projecting and array of sub-documents. Here is what I currently get from aggrgation:

{
  "_id": "581c8c3df1325f68ffd23386",
  "count": 14,
  "authors": [
    {
      "author": {
        "author": "57f246b9e01e6c6f08e1d99a",
        "post": "581c8c3df1325f68ffd23386"
      },
      "count": 13
    },
    {
      "author": {
        "author": "5824382511f16d0f3fd5aaf2",
        "post": "581c8c3df1325f68ffd23386"
      },
      "count": 1
    }
  ]
}

I want to $project the authors array so that the return would be this:

{
  "_id": "581c8c3df1325f68ffd23386",
  "count": 14,
  "authors": [
    {
      "_id": "57f246b9e01e6c6f08e1d99a",
      "count": 13
    },
    {
      "_id": "5824382511f16d0f3fd5aaf2",
      "count": 1
    }
  ]
}

How would I go about achieving that?

like image 604
Gregor Menih Avatar asked Nov 11 '16 10:11

Gregor Menih


People also ask

Can we use array in MongoDB?

Unlike relational database models, MongoDB documents can have fields which have values as arrays. The prototypical example in almost all MongoDB documentation is a document having a tags field, whose value is an array of strings, such as ["NoSQL", "Ruby", "MongoDB"] .

How do I pull an element from an array in MongoDB?

The $pull operator removes from an existing array all instances of a value or values that match a specified condition. The $pull operator has the form: { $pull: { <field1>: <value|condition>, <field2>: <value|condition>, ... } } To specify a <field> in an embedded document or in an array, use dot notation.


1 Answers

You can unwind the array and wind it u again after projecting. Something like this:

db.collectionName.aggregate([
{$unwind:'$authors'},
{$project:{_id:1,count:1,'author.id':'$authors.author.author','author.count':'$authors.count'}},
{$group:{_id:{_id:'$_id',count:'$count'},author:{$push:{id:'$author.id',count:'$author.count'}}}},
{$project:{_id:0,_id:'$_id._id',count:'$_id.count',author:1}}
])

the output for above will be:

{ 
    "_id" : "581c8c3df1325f68ffd23386", 
    "author" : [
        {
            "id" : "57f246b9e01e6c6f08e1d99a", 
            "count" : 13.0
        }, 
        {
            "id" : "5824382511f16d0f3fd5aaf2", 
            "count" : 1.0
        }
    ], 
    "count" : 14.0
}
like image 53
cartman619 Avatar answered Oct 02 '22 19:10

cartman619