Reputation: 305
I'm trying to update a parent document with an array of all of it's children document Ids using an upsert. The problem is the ID is only returned if the upsert caused an insert to occur.
I've got the following code which works when new children are being inserted but once one is updated the promise locks up due to the result's upsertedId being null
.
let promises = [];
parent.children.forEach(child => {
//Child contains everything except the _id
promises.push(database.collection('Children').updateOne(
child,
child,
{
upsert: true
}
));
});
Promise.all(promises).then(result => {
delete parent.children;
parent.childIds = result.map(upsert => new ObjectId(upsert.upsertedId._id)); //ONLY THERE ON INSERT?
database.collection('Parents').updateOne({
parentId: obj.parentId
}, obj, {
upsert: true
}).then(() => {
//some success functionality
}, error => {
//some error functionality
});
}, error => {
//some error functionality
});
Upvotes: 1
Views: 650
Reputation: 305
It appears the solution was to use the findOneAndUpdate
method. This method will find an object, updated it and then return the document. It also accepts the upsert
parameter thus an insert is performed when a specific document is not found.
In the case that an update is performed the result will contain the document under the value
field.
In the case that a insert is performed (when upsert is true) a the field lastErrorObject.upserted
will be set in the result object and the value
field will be null
.
Here is the code that fixed my issue:
let promises = [];
parent.children.forEach(child => {
promises.push(database.collection('Children').findOneAndUpdate(
child,
child,
{
upsert: true
}
));
});
Promise.all(promises).then(result => {
delete parent.children;
parent.childrenIds = result.map(upsert => new ObjectID(upsert.lastErrorObject.upserted || upsert.value._id));
database.collection('Parents').updateOne({
parentId: parent.parentId
}, obj, {
upsert: true
}).then(() => {
//some success functionality
}, error => {
//some error functionality
});
}, error => {
//some error functionality
});
Upvotes: 4