i am trying the logic ( insert if not exists , but if exists update the records )
i am new to MongoDB , but i use to do that with mysql , is it possible to achieve this using mongoDB ?
here is my code so far which is working well in case ( insert if not exists )
but not in ( update if exists )
$db = new MongoDB\Client($conn);
$collection = $db->auth->users;
$collection->createIndex(
array( "username" => 1 ),
array( "unique" => true )
);
$document = array(
"title" => "Mraaxs",
"fullname" => "John C12344",
"username" => "user1",
"age" => 22
);
$collection->updateOne(
array("username" => $document["username"]),
array('$setOnInsert' => $document),
array("upsert" => true)
);
CodePudding user response:
Most likely you need to change $setOnInsert
to $set
.
According to the documentation for $setOnInsert
:
If an update operation with upsert: true results in an insert of a document, then
$setOnInsert
assigns the specified values to the fields in the document. If the update operation does not result in an insert,$setOnInsert
does nothing.
So it behaves exactly as you described. $setOnInsert
works for "insert if not exists" and does nothing for "update if exists".
$set
will always update/put data into the document.
Here is a good example for your case from the documentation, using both $set
and $setOnInsert
.
db.products.updateOne(
{ _id: 1 },
{
$set: { item: "apple" },
$setOnInsert: { defaultQty: 100 }
},
{ upsert: true }
)
When the upsert parameter is true db.collection.updateOne()
- creates a new document
- applies the $set operation
- applies the $setOnInsert operation
The products collection contains the newly-inserted document:
{ "_id" : 1, "item" : "apple", "defaultQty" : 100 }
So the solution will be:
...
$collection->updateOne(
array("username" => $document["username"]),
array('$set' => $document),
array("upsert" => true)
);
Note: optionally, you can use $setOnInsert
to store created_at
for new documents:
$collection->updateOne(
array("username" => $document["username"]),
array('$set' => $document, '$setOnInsert' => ['created_at' => time()]),
array("upsert" => true)
);