I wrote a simple updateMany statement to add a now field in a collection called products. As new products may not have an onSale property it may be added to the first time when those products now become eligible for onSale. However, older products which had already been onSale need to be update with onSale:false. Here is my update statement. I need to update the onSale: false when the sale ends for products.
I also notice that version 8.0.3 no longer accepts the {multi:true} anymore.
public async updateProductsToOnSale(productIds: Array<string>, onSaleStatus: boolean): Promise<UpdateWriteOpResult | undefined> {
try {
return await Product.updateMany(
{
_id: {
$in: productIds
}
},
{ $set: { onSale: onSaleStatus } }, )
} catch (error) {
this.logger.error(error,`Update Failed for productIds ${productIds}`);
}
}
The behavior I see that sometimes no rows are updated. However, when I print out the matched count I get matchedCount:1 even though the update did not work. Will this update work for setting a new onSale property as well as for an existing onSale property? If not is there a way to accomplish that with one updateMany or do I need 2 , one for the existing onSale and another to set a new onSale property? Thanks
2
Answers
No,You don’t need two function, you can use bulkWrite
Mongoose bulk write doc
Yes you can do this with one
updateMany()
function if you use an Aggregation Pipeline.Using
$set
without a query condition as the first parameter will add theonSale
property to every document and by using a$cond
you can specify which documents will be set toonSaleStatus
via an$in
operator.If an
_id
is$in
your array ofproductIds
then set it toonSaleStatus
otherwise set it tofalse
.An example would be:
See HERE for a full working example.