skip to Main Content

I have a list of documents that looks like this:

_id: ObjectId('63c6a4b858612f44f37d4771')
type: "TypeA"
priority: 1

_id: ObjectId('627279d3ba7aef5d6418c867')
type: "TypeB"
priority: 2

The type here is unique so I can’t have two documents with the same type. Now I want to set the type as the object name, with _id and priority inside the object. Like this:

TypeA: {
    _id: ObjectId('63c6a4b858612f44f37d4771'),
    priority: 1
}

TypeB: {
    _id: ObjectId('627279d3ba7aef5d6418c867'),
    priority: 2
}

I’ve tried something like this:

{
    $project: {
        '$$this.type': {
            _id: '$_id',
            priority: '$priority'
        }
    }
}

I just need help with getting the value of type as the object key.

2

Answers


  1. You can use the $group aggregation operator in combination with the $addToSet operator to group the documents by the type field, and create an array of objects for each "type" group that contains the _id and priority fields.

    db.collection.aggregate([
       {
          $group:
             {
               _id: "$type",
               documents: { $push: { _id: "$_id", priority: "$priority" } }
             }
       }
    ])
    

    This will create a new array of objects for each unique type field, where the type field is the key of the object and the documents array contains the _id and priority fields

    Login or Signup to reply.
  2. To create a dynamic field name, create the object as an array of k v pairs, and use $arrayToObject like:

    db.collection.aggregate([
      {$project: {
          newDoc: [ {k:"$type", v: {_id:"$_id", priority: "$priority"}} ]
      }},
      {$replaceRoot: {newRoot: {$arrayToObject: "$newDoc"}}}
    ])
    

    Playground

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search