I have the following mongodb object:
{
"_id": ObjectId("4d0b9c7a8b012fe287547157"),
"messages": {
"0": {
"toUname": "Eamorr3",
"fromUname": "Eamorr2",
"time": 1292606586,
"id": "ABCDZZZ",
"subject": "asdf",
"message": "asdf",
"read": 0 //I want to change this to 1!
},
"1": {
"toUname": "Eamorr1",
"fromUname": "Eamorr3",
"time": 1292606586,
"id": "EFGHZZZ",
"subject": "asdf2",
"message": "asdf2",
"read": 0
}
},
"uname": "Eamorr3"
}
How do I set "read" to 1 where id=ABCDZZZZ? I'm using PHP.
I've tried the following command:
$driverInboxes->update(array('uname'=>$uname),array('$set'=>array('messages'=>array('id'=>$id,'read'=>'1'))));
But when I do this, overwriting occurs and I get:
{
"_id": ObjectId("4d0b9c7a8b012fe287547157"),
"messages": {
"id": "j7zwr2hzx14d3sucmvp5",
"read": "1"
},
"uname": "Eamorr3"
}
I'm totally stuck. Any help much appreciated.
Do I need to pull the entire array element, modify and and push it back in again?
Many thanks in advance,
You can use the updateOne() or updateMany() methods to add, update, or remove array elements based on the specified criteria. It is recommended to use the updateMany() method to update multiple arrays in a collection.
To update all the elements of an array, call the forEach() method on the array, passing it a function. The function gets called for each element in the array and allows us to update the array's values. Copied! const arr = ['zero', 'one', 'two']; arr.
So, Adding a new field to an array is possible by using the update operation. $push operator is used to insert the field inside the array and if we want to add multiple fields, use $each inside $push.
In MongoDB, the $push operator is used to appends a specified value to an array. If the mentioned field is absent in the document to update, the $push operator add it as a new field and includes mentioned value as its element. If the updating field is not an array type field the operation failed.
If you read your command, you're actually saying: "UPDATE WHERE uname = Eamorr3 SET messages equal to this array (id=blah,read=1)"
When you do a $set
on messages
, you're basically instructing it to take your array as the new value.
However, it looks like you're trying to update a specific message as read which is just a little more complex. So there are two hurdles here:
1: You're actually updating messages.0.read
If you do array('$set' => array( 'messages.0.read' => 1 ) )
, you will update the correct element. Follow that chain, messages
is a javascript object and you want to update the property 0
. The property 0
is itself a javascript object which contains the property read
which you want to update.
Can you see how you're updating messages.0.read
?
This brings us to problem #2.
2: the 0
is a problem for you
If you look at the way you've structured the data in Mongo, the messages object is really sub-par. The "0" and "1" are currently acting as "ids" and they're not very useful. Personally, I would structure your objects with the actual IDs in place of "0" or "1".
So your objects would look like the following:
{
"_id": ObjectId("4d0b9c7a8b012fe287547157"),
"messages": {
"ABCDZZZ": {
"toUname": "Eamorr3",
"fromUname": "Eamorr2",
"time": 1292606586,
"subject": "asdf",
"message": "asdf",
"read": 0 //I want to change this to 1!
}
},
"uname": "Eamorr3"
}
Now you're update command becomes this:
array('$set' => array( 'messages.ABCDZZZ.read' => 1 ) )
This structure makes it much easier to update a specific message or a specific portion of a message.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With