最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

mongoose - update mongodb 's array with $addToSet and set array's length with { '$size': &#3

programmeradmin0浏览0评论

I am working on mongodb which has model like the below

const appJobSchema = new mongoose.Schema({
    data:[
        { type:Schema.Types.Mixed}
    ],
    stat:{
      dataCount: { type:Number , default: 0 },
    }
})

what i need to do is to update a few records to the mongodb array field - data, at the same time update the latest array length to the stat.dataCount field.

export async function updateDataById(id:string, records:any[]){
  return await model.updateOne({'_id':id}, {  
    '$addToSet': { 'data': { '$each': records } } ,  
    '$set':{ 
      'stat.dataCount': { $size: "$data" }  } 
  } );
}

but i got an error saying

uncaughtException: Cast to Number failed for value "{ '$size': '$data' }" (type Object) at path "stat.dataCount"

any idea how would I do it?

update

first try on the pipeline

return await model.updateOne({'_id':id}, 
    [
    {
      "$set": {
        "data": {
          $concatArrays: [ "$data",  records  ]
        }
      }
    },
    { 
      '$set':{ 
        'stat.dataCount': { $size: "$data" }  }  
    }
  ]);

it is working but the problem is solely adding values to data array would cause the duplicate values, and that is why I have to use $addToSet in order to remove the duplicate.

second try on the pipeline

Model.updateOne({'_id':id},
    [
      {  '$addToSet': { 'data': { '$each': records } },  '$inc':{ 'runCount': 1  } , 
      { 
        '$set':{ 
          'stat.dataCount': { $size: "$data" }  }  
      }
  ]);

it throws out uncaughtException: Invalid update pipeline operator: "$addToSet". same for $inc.

finally get it working by $setUnion with pipeline,

await Model.updateOne({'_id':id},
    [   
      {
      "$set": {
        "data": {
          $setUnion: [ "$data",  records  ]
        }
      }
    },
    { 
      '$set':{ 
        'stat.dataCount': { $size: "$data" }  }  
    },
  ]);

but what if i need to use $inc, it seems still a problem.

I am working on mongodb which has model like the below

const appJobSchema = new mongoose.Schema({
    data:[
        { type:Schema.Types.Mixed}
    ],
    stat:{
      dataCount: { type:Number , default: 0 },
    }
})

what i need to do is to update a few records to the mongodb array field - data, at the same time update the latest array length to the stat.dataCount field.

export async function updateDataById(id:string, records:any[]){
  return await model.updateOne({'_id':id}, {  
    '$addToSet': { 'data': { '$each': records } } ,  
    '$set':{ 
      'stat.dataCount': { $size: "$data" }  } 
  } );
}

but i got an error saying

uncaughtException: Cast to Number failed for value "{ '$size': '$data' }" (type Object) at path "stat.dataCount"

any idea how would I do it?

update

first try on the pipeline

return await model.updateOne({'_id':id}, 
    [
    {
      "$set": {
        "data": {
          $concatArrays: [ "$data",  records  ]
        }
      }
    },
    { 
      '$set':{ 
        'stat.dataCount': { $size: "$data" }  }  
    }
  ]);

it is working but the problem is solely adding values to data array would cause the duplicate values, and that is why I have to use $addToSet in order to remove the duplicate.

second try on the pipeline

Model.updateOne({'_id':id},
    [
      {  '$addToSet': { 'data': { '$each': records } },  '$inc':{ 'runCount': 1  } , 
      { 
        '$set':{ 
          'stat.dataCount': { $size: "$data" }  }  
      }
  ]);

it throws out uncaughtException: Invalid update pipeline operator: "$addToSet". same for $inc.

finally get it working by $setUnion with pipeline,

await Model.updateOne({'_id':id},
    [   
      {
      "$set": {
        "data": {
          $setUnion: [ "$data",  records  ]
        }
      }
    },
    { 
      '$set':{ 
        'stat.dataCount': { $size: "$data" }  }  
    },
  ]);

but what if i need to use $inc, it seems still a problem.

Share Improve this question edited Feb 4 at 1:02 user824624 asked Feb 3 at 15:16 user824624user824624 8,08035 gold badges119 silver badges210 bronze badges 2
  • 1 mongoplayground/p/uvLO3drlZ9q – cmgchess Commented Feb 3 at 15:33
  • MongoDB $inc is the update operator, since you change it to pipeline, you should revamp to $set and $sum to increment the value: { $set: { 'runCount': { $sum: [ '$runCount', 1] } } } – Yong Shun Commented Feb 4 at 1:09
Add a comment  | 

1 Answer 1

Reset to default 2

As you are switching to the update pipeline to use the aggregation operator, the update operator is not supported. You need to switch to all aggregation operators, such as $sum to replace the $inc.

await Model.updateOne({'_id':id},
  [   
    {
      "$set": {
        "data": {
          $setUnion: [ "$data",  records  ]
        },
        "runCount": { 
          $sum: [ "$runCount", 1 ]  
        }
      }
    }
  },
  { 
    "$set": { 
      "stat.dataCount": { $size: "$data" }  
    }
  },
]);

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论