Home > front end >  Convert $objectToArray map element to String
Convert $objectToArray map element to String

Time:02-11

I have a collection in database that I am trying to retrieve some data from it , the query is working fine when $orderID has string elements , but is failing when $orderID has some numbers in array , and it is throwing

query failed: (Location40395) PlanExecutor error during aggregation :: caused by :: $arrayToObject requires an array of key-value pairs, where the key must be of type string. Found key type: double

I think there must be some old data when we were saving orderID as a number so that is why it is failing from some range of dates

Query

{
    "Order_Details": {
        "$map": {
            "input": {
                "$objectToArray": {
                    "$arrayToObject": {
                        "$zip": {
                            "inputs": [
                                "$orderID",
                                "$total_value_of_order"
                            ]
                        }
                    }
                }
            },
            "as": "el",
            "in": {
                "orderID": "$$el.k",
                "total_value_of_order": "$$el.v"
            }
        }
    }
}

I am trying to typecast el.k to string I am using $toString but can't seem to work , the way I am trying it is

{
    "as": "el",
    "in": {
        "orderID": {
            "$toString": "$$el.k"
        },
        "total_value_of_order": "$$el.v"
    }
}

Example collection

[
  {
    "_id": ObjectId("5e529ee5f8647eb59e5620a2"),
    "visitID": "dVmy7flXFHzzkn9HiMt8IoWvthoTZW",
    "date": ISODate("2022-02-08T16:29:13.413Z"),
    "control": true,
    "orderID": [
      122343242
    ],
    "target": "test",
    "total_value_of_order": [
      60
    ]
  }
]

CodePudding user response:

You are close, the approach is fine. you just have a couple of syntax issues. The major thing that needs to change is the input for $arrayToObject, currently your input looks like this:

[[number, number], [number, number]]

However $arrayToObject expects input in a certain format:

[{k: string, v: value}]

So this it what we'll add, like so:

db.collection.aggregate([
  {
    $project: {
      "Order_Details": {
        "$map": {
          "input": {
            "$objectToArray": {
              "$arrayToObject": {
                $map: {
                  input: {
                    "$zip": {
                      "inputs": [
                        "$orderID",
                        "$total_value_of_order"
                      ]
                    }
                  },
                  in: {
                    k: {
                      $toString: {
                        "$arrayElemAt": [
                          "$$this",
                          0
                        ]
                      }
                    },
                    v: {
                      "$arrayElemAt": [
                        "$$this",
                        1
                      ]
                    }
                  }
                }
              }
            }
          },
          "as": "el",
          "in": {
            "orderID": "$$el.v",
            "total_value_of_order": "$$el.k"
          }
        }
      }
    }
  }
])

Mongo Playground

Notice the "orderid" format changes to string which affects it's structure, I recommend just switching between the k and v in the pipeline, like this

  • Related