问题
I have to insert multiple documents if they don't already exist, but the important thing is that in the query results I need to have IDs of both the inserted and already existing items.
I'm trying with the following bulkWrite
operation:
// external_id is a unique id other than the mongo _id
let items = [
{external_id: 123, name: "John"},
{external_id: 456, name: "Mike"},
{external_id: 789, name: "Joseph"}
];
db.collection("my_collection")
.bulkWrite(
items.map((item) => {
return {
updateOne: {
filter: { external_id: item.external_id },
update: { $setOnInsert: item},
upsert: true,
},
};
})
);
The problem is that the BulkWriteResult
return only the _id
of the inserted items in upsertedIds
, while for the existing items return only the nMatched
number.
The other solution I have think about is to make (1) a find
over an array of ids, (2) check the results for the ones already existing, and (3) then insertMany
for the new ones:
let ids = [123, 456, 789];
let items = [
{external_id: 123, name: "John"},
{external_id: 456, name: "Mike"},
{external_id: 789, name: "Joseph"}
];
// STEP 1: Find alredy existings items
db.collection("my_collection")
.find({ external_id: { $in: ids } })
.toArray(function (err, existingItems) {
// If John already exist
// existingItems = [{_id: ObjectId, external_id: 123, name: "John"}]
// STEP 2: Check which item has to be created
let itemsToBeCreated = items.filter((item) =>
!existingItems.some((ex) => ex.external_id === item.external_id)
);
// STEP 3: Insert new items
db.collection("my_collection")
.insertMany(itemsToBeCreated, function (err, result) {
// FINALLY HERE I GET ALL THE IDs OF THE EXISTING AND INSERTED ITEMS
});
});
With this solution I'm concerned about performance, because these operations are fired 100K times a day for 10 items each, and about 90% of the times the items are new. So 900K new items and 100K already existing.
I would like to know if there is a better way of achieving this.
Thanks in advance
来源:https://stackoverflow.com/questions/65342270/mongodb-get-ids-of-inserted-and-existing-documents-after-insert-if-not-exist