'What is causing bulkWrite to write incorrectly?
I am trying to write some unit tests and I have the following single document in my rates collection:
{
_id: new ObjectId("623bda93f0ead42eaf6b0957"),
baseRate: 100,
propertyId: new ObjectId("623bda93f0ead42eaf6b0934"),
ratePlanId: new ObjectId("623bda93f0ead42eaf6b094e"),
date: 2022-03-30T00:00:00.000Z,
closedToArrival: true,
closedToDeparture: true,
closedOut: true,
kind: 'parentRate',
__v: 0
}
I want to update the current document and insert 2 more:
const query = [{
updateOne: {
filter: {
propertyId: new ObjectId("623bda4c0c52e177121cf5a4"),
ratePlanId: new ObjectId("623bda4c0c52e177121cf5c2"),
date: 2022-03-30T00:00:00.000Z
},
update: { '$set': {
baseRate: 50,
closedToArrival: true,
closedToDeparture: true,
closedOut: true,
kind: 'parentRate'
} },
upsert: true
}
},
{
updateOne: {
filter: {
propertyId: new ObjectId("623bda4c0c52e177121cf5a4"),
ratePlanId: new ObjectId("623bda4c0c52e177121cf5c2"),
date: 2022-03-31T00:00:00.000Z
},
update: { '$set': {
baseRate: 50,
closedToArrival: true,
closedToDeparture: true,
closedOut: true,
kind: 'parentRate'
} },
upsert: true
}
},
{
updateOne: {
filter: {
propertyId: new ObjectId("623bda4c0c52e177121cf5a4"),
ratePlanId: new ObjectId("623bda4c0c52e177121cf5c2"),
date: 2022-04-01T00:00:00.000Z
},
update: { '$set': {
baseRate: 50,
closedToArrival: true,
closedToDeparture: true,
closedOut: true,
kind: 'parentRate'
} },
upsert: true
}
}];
const bulkWrite = await Rate.bulkWrite(query, { ordered: false });
if (bulkWrite.result.ok === 1) {
const rates = await Rate.find({});
console.log(rates);
}
bulkWrite.result contains the following:
{
ok: 1,
writeErrors: [],
writeConcernErrors: [],
insertedIds: [],
nInserted: 0,
nUpserted: 2,
nMatched: 1,
nModified: 1,
nRemoved: 0,
upserted: [
{ index: 1, _id: new ObjectId("623bdbdcb18ce85894eb752c") },
{ index: 2, _id: new ObjectId("623bdbdcb18ce85894eb752d") }
]
}
It would appear that 1 was modified and 2 were upserted, however when I then do a query to see which documents are present, the one that was previously there was not modified, and the other two new documents are missing the rate and kind fields:
[
{
_id: new ObjectId("623bda93f0ead42eaf6b0957"),
baseRate: 100,
propertyId: new ObjectId("623bda93f0ead42eaf6b0934"),
ratePlanId: new ObjectId("623bda93f0ead42eaf6b094e"),
date: 2022-03-30T00:00:00.000Z,
closedToArrival: true,
closedToDeparture: true,
closedOut: true,
kind: 'parentRate',
__v: 0
},
{
_id: new ObjectId("623bda93b18ce85894eb744f"),
date: 2022-03-31T00:00:00.000Z,
propertyId: new ObjectId("623bda93f0ead42eaf6b0934"),
ratePlanId: new ObjectId("623bda93f0ead42eaf6b094e"),
closedOut: true,
closedToArrival: true,
closedToDeparture: true
},
{
_id: new ObjectId("623bda93b18ce85894eb7450"),
date: 2022-04-01T00:00:00.000Z,
propertyId: new ObjectId("623bda93f0ead42eaf6b0934"),
ratePlanId: new ObjectId("623bda93f0ead42eaf6b094e"),
closedOut: true,
closedToArrival: true,
closedToDeparture: true
}
]
Any ideas why that is?
Solution 1:[1]
It turns out that the problem was my Rate model has a discriminator. The discriminator key is kind and the baseRate property is only available on the parentRate kind.
To quote AbdelrahmanHafez from this Github issue
When sending an update command to the database, at this point we don't know if the document exists or not, and if it exists, we don't know which kind it is, so unless you provide information as to what kind the document is, there is no way to know.
In other words, to get it to work, you need to add the discriminator key to the filter:
{
updateOne: {
filter: {
propertyId: new ObjectId("623bda4c0c52e177121cf5a4"),
ratePlanId: new ObjectId("623bda4c0c52e177121cf5c2"),
date: 2022-04-01T00:00:00.000Z,
kind: 'parentRate',
},
update: { '$set': {
baseRate: 50,
closedToArrival: true,
closedToDeparture: true,
closedOut: true,
} },
upsert: true
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Mike |
