Home > database >  MongoDB multiply object values?
MongoDB multiply object values?

Time:05-26

I have following structure in MongoDB:

{
  "system_id": 133657,
  "type": "personal",
  "prices": {
    "7": {
      "min": 0.05,
      "max": 0.05,
      "avg": 0.05,
      "sales": 1
    },
    "14": {
      "min": 0.05,
      "max": 0.05,
      "avg": 0.05,
      "sales": 3
    },
    "30": {
      "min": 0.03,
      "max": 0.04,
      "avg": 0.03,
      "sales": 8
    }
  },
  "prices_updated_at": { "$date": "2022-05-25T04:48:43.469Z" }
}

Is it possible to iterate and multiply all price values (min, max, avg) by for example 2 and output it in the same structure? Keys (1, 7, 14) are not fixed and can have different values, depending on sale stats.

All I've found was array and not object related.

Thanks for any help!

CodePudding user response:

You can use the following trick:

 db.collection.aggregate([
 {
  "$addFields": {
  "prices": {
    "$objectToArray": "$prices"
   }
  }
 },
 {
 "$addFields": {
  "prices": {
    $map: {
      input: "$prices",
      as: "p",
      in: {
        "k": "$$p.k",
        "v": {
          "min": {
            $multiply: [
              "$$p.v.min",
              2
            ]
          },
          "max": {
            $multiply: [
              "$$p.v.max",
              2
            ]
          },
          "avg": {
            $multiply: [
              "$$p.v.avg",
              2
            ]
          },
          "sales": "$$p.v.sales"
         }
        }
      }
    }
   }
  },
  {
   "$addFields": {
  "prices": {
    "$arrayToObject": "$prices"
   }
  }
 }
])

Explained:

  1. Convert the prices object to array
  2. Now use $map to multiply by 2 for all min,max and avg values
  3. Convert back from array to object ( back to original structure )

Playground

Same thing can be done in single $addFields operation and it is expected to perform better , but not very human readable:

Playground2

  • Related