I have two models
// Product model
const ProductSchema = {
vendors: [{ type: Schema.Types.ObjectId, ref: 'Vendor' }],
mainVendor: { type: Schema.Types.ObjectId, ref: 'Vendor' },
}
// Vendor model
const VendorSchema = { ... }
When I delete a Vendor
, I want all Products
with mainVendor
field of deleted Vendor
‘s _id
to be replaced with the first vendor
of vendors
array. If vendors
array is empty, I want mainVendor
to be set to null
.
Say I have Product
const product = {
mainVendor: 'mainVendorObjectId'
vendors: ['secondVendorObjectid', 'thirdVendorObjectId']
}
When I delete Vendor
with mainVendorObjectId
_id
, I want my product
to be
const product = {
mainVendor: 'secondVendorObjectId',
vendors: ['thirdVendorObjectId']
}
If I have a product
with empty vendors
array
const product = {
mainVendor: 'mainVendorObjectId',
vendors: []
}
After deleting Vendor
with mainVendorObjectId
_id
I want my product to be like
const product = {
mainVendor: null,
vendors: []
}
I want to run it in post
hook.
What I have now
VendorSchema.post('findOneAndDelete', async function (res: TVendorModel) {
try {
const products = await ProductModel.updateMany(
{ mainVendor: res._id },
{ $expr: { $set: { mainVendor: '$vendors.0' } } }
);
} catch (error) {
console.error(error);
}
});
but it doesn’t work and it won’t set mainVendor
to null
if vendors
array is empty.
2
Answers
A bit long query, but you can try with Update with aggregation pipeline.
With
$cond
operator to check whethervendors
is an empty array, if yes setnull
, else take the first value from thevendors
array tomainVendor
field.For the
vendors
field, it does the same concept asmainVendor
field, the outcome will be different in removing the first item fromvendors
array.Sample Mongo Playground
Too late but this is my solution
$first
extracts the first object of an array$ifNull
checks if $first operation is null, if true, adds null$slice
extracts a portion of the array$sum
does a sum operation. In this case is just a trick to avoid errors when the length of the array is 0 (because $slice needs a value greater than 0)