Reputation: 3309
I try to import data from an external source into my mongodb with php. Every row from the external data is one mongodb document. Every row has an unique id called uid.
Now I am trying the following: I want to insert a new row, if no document with the same uid exists already (Upsert).
For a single document, I would do the following:
$collection->updateOne(
["uid" => "2"],
['$set' => [
"newfield" => date("Y-m-d H:i:s"),
"name" => "Test"
]],
[
"upsert" => true
]
);
Step 1:
Is it possible to override the complete document, not just set specific fields? Something like this:
$collection->updateOne(
["uid" => "2"],
[
"newfield" => date("Y-m-d H:i:s"),
"name" => "Test"
],
[
"upsert" => true
]
);
This is not working, since i get a First key in $update argument is not an update operator
error. How to do it?
Step 2
For performance reasons, I want to use insertMany or updateMany function to bulk upsert multiple documents.
But what filter do I need for updateMany:
$db->updateMany(
[???????],
[
"newfield" => date("Y-m-d H:i:s"),
"name" => "XXX"
],
[
"upsert" => true
]
);
Upvotes: 4
Views: 4779
Reputation: 37048
The questions are totally independent.
The first:
Use update with multi: false
(which is default) instead of updateOne. The former allows to replaces an existing document entirely.
The second:
updateMany doesn't work this way. It is more like update with multi: true
- it applies update operations to all documents that match the filter. When used with upsert: true
the filter fields should be uniquely indexed to avoid multiple upserts.
If you want to perform multiple upserts with individual filters in one go, you can use bulk update:
$bulk = new MongoDB\Driver\BulkWrite(['ordered' => false]);
$bulk->update(["uid" => "2"], [
"newfield" => date("Y-m-d H:i:s"),
"name" => "Test"
]]);
$bulk->update(["uid" => "3"], [
"newfield" => date("Y-m-d H:i:s"),
"name" => "Another Test"
]]);
$bulk->update(["uid" => "4"], [
"newfield" => date("Y-m-d H:i:s"),
"name" => "One more Test"
]]);
$result = $manager->executeBulkWrite('db.collection', $bulk, $writeConcern);
Please read the page behind the last link for limitations of bulk operations.
Upvotes: 3