Search code examples
mongodbmongoosemongoose-schema

How to update a field in an array element with another field in the same element?


import mongoose from 'mongoose'

const holderSchema = new mongoose.Schema(
    {
        walletId: {
            type: String,
            required: true,
            unique: true,
        },
        solBalance: {
            type: Number,
            default: 0,
            min: 0,
        },
        liquidityPools: [
            {
                collectionId: {
                    type: mongoose.Schema.Types.ObjectId,
                    required: true,
                },
                lpTokens: {
                    type: Number,
                    required: true,
                    min: 0,
                },
                feeEarned: {
                    type: Number,
                    default: 0,
                    min: 0,
                },
                isActive: {
                    type: Boolean,
                    default: true,
                },
            },
        ],
    },
    { timestamps: true }
)

export default mongoose.models.Holder || mongoose.model('Holder', holderSchema)

In this model how can I do something like this - liquidityPools.feeEarned += liquidityPools.lpTokens /100 for array elements of all docs with liquidityPools.collectionId as 5

await Holder.updateMany(
                        { 'liquidityPools.collectionId': collectionId, 'liquidityPools.isActive': true },
                        {
                            $inc: {
                                'liquidityPools.$[elem].feeEarned': {
                                    $multiply: [
                                        'elem.lpTokens',100
                                    ],
                                },
                            },
                        }
                    )
                 })`

This is what I tried but using $multiple inside $inc doesn't seem to work.


Solution

  • You can update MongoDB documents using the aggregation pipeline (docs).

    Here is how the query might look like:

    db.collection.update({
      "liquidityPools.collectionId": "60d1a0a0fd92f81b8e7a1dc1",
      "liquidityPools.isActive": true
    },
    [
      {
        $set: {
          liquidityPools: {
            $map: {
              input: "$liquidityPools",
              as: "pool",
              in: {
                $cond: [
                  {
                    $eq: [
                      "$$pool.collectionId",
                      "60d1a0a0fd92f81b8e7a1dc1"
                    ]
                  },
                  {
                    collectionId: "$$pool.collectionId",
                    lpTokens: "$$pool.lpTokens",
                    feeEarned: {
                      $add: [
                        "$$pool.feeEarned",
                        {
                          $multiply: [
                            "$$pool.lpTokens",
                            100
                          ]
                        },
                        
                      ],
                      
                    },
                    isActive: "$$pool.isActive",
                    
                  },
                  "$$pool",
                  
                ],
                
              },
              
            },
            
          },
          
        },
        
      },
      
    ])
    

    Here is MongoDB playground link to see the query work.