Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP/MongoDB: update a value in an array

Tags:

php

mongodb

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,

like image 375
Eamorr Avatar asked Dec 17 '10 18:12

Eamorr


People also ask

How do you update an element in an array in MongoDB?

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.

How do you update an array?

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.

How do I add a field to an array in MongoDB?

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.

How do you push an object into an array in MongoDB query?

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.


1 Answers

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.

like image 189
Gates VP Avatar answered Sep 19 '22 00:09

Gates VP