Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MongoDb Aggregation - project values as keys and corresponding array value as values

In mongodb, I have a get object in below shape after running aggregation.

 {
      "_id": 1,
      "specificationList": {
        "key": "Memory & Storage Features",
        "values": [
          {
            "key": "Internal Storage",
            "value": [
              "32 KB"
            ]
          },
          {
            "key": "RAM",
            "value": [
              "32 MB"
            ]
          },
          {
            "key": "Expandable Storage",
            "value": [
              "8 GB"
            ]
          },
          {
            "key": "Supported Memory Card Type",
            "value": [
              "MicroSD"
            ]
          }
        ]
      }
    }

From above document , how could I get object in below shape , in next aggregation pipeline. I need to get to below shape so as to make code cleaner. I am using aggregation to arrive at above shape (so want to append another pipeline), and it would be nice to know what aggregation pipeline to get at below shape

{
 "specList” : {
    “Internal Storage”: “32 KB”,
   “RAM”:”32 MB”,
   “Expandable Storage”:”8 GB”,
    “Supported Memory Card Type”:”MicroSD”
   }
}
like image 493
Shambu Avatar asked Feb 26 '18 08:02

Shambu


People also ask

Which aggregation method is preferred for use by MongoDB?

The pipeline provides efficient data aggregation using native operations within MongoDB, and is the preferred method for data aggregation in MongoDB. The aggregation pipeline can operate on a sharded collection. The aggregation pipeline can use indexes to improve its performance during some of its stages.

What is Project in MongoDB aggregation?

The $project takes a document that can specify the inclusion of fields, the suppression of the _id field, the addition of new fields, and the resetting of the values of existing fields. Alternatively, you may specify the exclusion of fields.

What are the differences between using aggregate () and find () in MongoDB?

With aggregate + $match, you get a big monolithic BSON containing all matching documents. With find, you get a cursor to all matching documents. Then you can get each document one by one.


1 Answers

Without knowing the full pipeline, you can use the $arrayToObject operator which converts an array into a single document but the array must contain two fields, k and v where the k field contains the field name and the v field contains the value of the field. In the above aggregate document you would need to map the values array to the above format which the $arrayToObject operator can then happily convert.

Consider adding a $project pipeline step which uses the $map operator to change the array structure and then apply the result of the transformation to the desired object.

The following illustrates this:

db.collection.aggregate([
    { ... }, // <-- previous pipeline
    {
        "$project": {
            "specList": {
                "$arrayToObject": {
                    "$map": {
                        "input": "$specificationList.values",
                        "as": "el",
                        "in": {
                            "k": "$$el.key",
                            "v": { "$arrayElemAt": ["$$el.value", 0] }
                        }
                    }
                }
            }
        }
    }
])
like image 75
chridam Avatar answered Oct 19 '22 00:10

chridam