Home > Software engineering >  Mongoose - renaming object key within array
Mongoose - renaming object key within array

Time:03-11

I have this one schema

{
  _id: "123456",
  id: "123",
  inventory: [
    {
      id: "foo",
      count: 0
    },
    {
      id: "bar",
      count: 3
    }
  ]
}

I wanted every "count" keys in the inventory array to be "price" which will look like this at the end:

{
  _id: "123456",
  id: "123",
  inventory: [
    {
      id: "foo",
      price: 0
    },
    {
      id: "bar",
      price: 3
    }
  ]
}

And I've tried this

Model.updateOne({ id: "123" }, { $unset: { inventory: [{ count: 1 }] } } )

But it seems to be deleting the "inventory" field itself

CodePudding user response:

The first thing here is to try to use $rename but how the docs explain:

$rename does not work if these fields are in array elements.

So is necessary to look for another method. So you can use this update with aggregation query:

This query uses mainly $map, $arrayToObject and $objectToArray. The trick here is:

  • Create a new field called inventory (overwrite existing one)
  • Iterate over every value of the array with $map, and then for each object in the array use $objectToArray to create an array and also iterate over that second array using again $map.
  • Into this second iteration create fields k and v. Field v will be the same (you don't want to change the value, only the key). And for field k you have to change only the one whose match with your condition, i.e. only change from count to price. If this condition is not matched then the key remain.
db.collection.update({},
[
  {
    $set: {
      inventory: {
        $map: {
          input: "$inventory",
          in: {
            $arrayToObject: {
              $map: {
                input: {$objectToArray: "$$this"},
                in: {
                  k: {
                    $cond: [
                      {
                        $eq: ["$$this.k","count"]
                      },
                      "price",
                      "$$this.k"
                    ]
                  },
                  v: "$$this.v"
                }
              }
            }
          }
        }
      }
    }
  }
])

Example here

  • Related