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 Answer
Reset to default 2As 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" }
}
},
]);
$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