user471011
user471011

Reputation: 7374

MongoDb: How to transform existing document to expected structure?

The existing MongoDB document looks like this:

  {
    "_id": "unique_id",
    "name": "some-name",
    "description": "some-description",
    "modified": "11-11-2021",
    "modifiedBy": "root"
  }

I need to change the structure of the document, as a result of transformation I expect to see the following Document:

  {
    "_id": "unique_id",
    "name": "some-name",
    "description": "some-description",
    "changes": [
      {
        "modified": "admin",
        "modifiedBy": "root"
      }
    ]
  }

I've tried the following aggregation query:

  {
    $project: {
      name: 1,
      description: 1,
      changes: [
        {
          "$modified",
          "$modifiedBy"
        }
      ]
    }
  }

But code above concatenates fields in the array as Strings, but I want to see 1 element in the array that is embedded document, not separate strings.

Upvotes: 0

Views: 586

Answers (2)

Haniel Baez
Haniel Baez

Reputation: 1690

You can use the $addFields, as the name implite it adds the new fields, and then use the $project to exclude the modified and modifiedBy fields.

 db.collection.aggregate([
  {
    $addFields: {
      "changes": [
        {
          modified: "$modified",
          modifiedBy: "$modifiedBy"
        }
      ]
    }
  },
  {
    $project: {
      modified: 0,
      modifiedBy: 0
    }
  }
])

Output:

 [
  {
    "_id": "unique_id",
    "changes": [
      {
        "modified": "11-11-2021",
        "modifiedBy": "root"
      }
    ],
    "description": "some-description",
    "name": "some-name"
  }
]

Upvotes: 1

grodzi
grodzi

Reputation: 5703

You projected to some array. You can project into objects as well

db.dummy.remove({})
db.dummy.insert({name:'n', description:'d', modified:'now', modifiedBy:'me'})
projo = {
  name: 1,
  description: 1,
  changes: [
    {
      modified: '$modified',
      modifiedBy: '$modifiedBy'
    }
  ]
}
printjson(db.dummy.findOne({}, projo)) // mongo >= 4.4 or use aggregate
/*
{
  "_id" : ObjectId("6041c873b051129dbb0c0f72"),
  "name" : "n",
  "description" : "d",
  "changes" : [
    {
      "modified" : "now",
      "modifiedBy" : "me"
    }
  ]
}
*/

playground

Upvotes: 1

Related Questions