Search code examples
node.jsmongodbmongodb-querynosql

$Subtract and other artihmetic operators returning Object instead of int


Problem

  • I made some code to perform arithmetic operations as I am working on billing software.
  • This code snippet is causing issues
    await shopCollection.updateOne(
            { Barcode: elem.Barcode },
            {
              $set: {
                Quantity: { $subtract: ["$Quantity", #elem.Quantity] },
                SalesQuantity: {
                  $add: [{ $ifNull: ["$SalesQuantity", 0] }, elem.Quantity],
                },
                Profit: { $subtract: ["$SalesPrice", "$CostPrice"] },
                TotalProfit: {
                  $add: ["$TotalProfit", { $multiply: ["$Profit", elem.Quantity] }],
                },
                SalesTotal: {
                  $add: [
                    "$SalesTotal",
                    { $multiply: ["$SalesPrice", elem.Quantity] },
                  ],
                },
              },
            },
            { upsert: true, returnOriginal: false }
          );

Entire code : https://pastebin.com/b6Zzhv16

It returns a object instead of Int like so

comparison Image

  • I am using ubuntu ,running the mongodb community edition and I am not using mongoose or schemas

Solution

  • to avoid this you will have to use aggregation pipeline with the updateOne operation.

    Apart from that few issues I found

    1. Since you are creating the Profit field inside the $set and you are trying to refer to that field in the same $set you will have to do in a new pipeline $set stage.
    2. Since you don't have TotalProfit profit field in your initial data you will have to write an ifNull check before adding otherwise you end up with null
    await shopCollection.updateOne({
      Barcode: elem.Barcode
    },
    [
      {
        $set: { 
          Quantity: { $subtract: [ "$Quantity", elem.Quantity ] },
          SalesQuantity: { $add: [ { $ifNull: [ "$SalesQuantity", 0 ] }, elem.Quantity ] },
          Profit: { $subtract: [ "$SalesPrice", "$CostPrice" ] },
          SalesTotal: { $add: [ "$SalesTotal", { $multiply: [ "$SalesPrice", elem.Quantity ] } ] }
        }
      },
      {
        $set: {
          TotalProfit: { $add: [ { $ifNull: [ "$TotalProfit", 0 ] }, { $multiply: [ "$Profit", elem.Quantity ] } ] }
        }
      }
    ],
      { upsert: true, returnOriginal: false }
    );
    

    playground