14

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”
   }
}
4
  • Can you show us the complete aggregate pipeline up to that stage? Commented Feb 26, 2018 at 8:51
  • i think this is not an aggregation issue but a mapping issue ? Commented Feb 26, 2018 at 8:53
  • @chridam, complete aggregation pipeline is quite a code, and for focus of problem, i presented the shape of the object after the current aggregation setup. Commented Feb 26, 2018 at 11:39
  • Ideally would like to see the last pipeline that produces the above result, if that could be tweaked to produce values like { "k": "RAM", "v": "32 MB" } instead of { "key": "RAM", "value": ["32 MB"] } then you can simply apply the $arrayToObject operator within a $project step as your final pipeline stage otherwise you would need to map the values to the above recommended shape, like in the answer I provided below. Commented Feb 26, 2018 at 11:43

1 Answer 1

18

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] }
                        }
                    }
                }
            }
        }
    }
])
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.