PHP/MongoDB: обновить значение в массиве

У меня есть следующий объект mongodb:

{
   "_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"
}

Как установить "read" в 1, где id = ABCDZZZZ? Я использую PHP.

Я пробовал следующую команду:

$driverInboxes->update(array('uname'=>$uname),array('$set'=>array('messages'=>array('id'=>$id,'read'=>'1'))));

Но когда я это делаю, происходит переписывание, и я получаю:

{
   "_id": ObjectId("4d0b9c7a8b012fe287547157"),
   "messages": {
     "id": "j7zwr2hzx14d3sucmvp5",
     "read": "1"
  },
   "uname": "Eamorr3"
}

Я полностью застрял. Любая помощь очень ценится.

Нужно ли мне тянуть весь элемент массива, изменять его и снова вставлять?

Большое спасибо заранее,

Ответы

Ответ 1

Если вы прочтете свою команду, вы на самом деле говорите: "UPDATE WHERE uname = Eamorr3 SET сообщения, равные этому массиву (id = blah, read = 1)"

Когда вы выполняете $set on messages, вы в основном поручаете ему принять ваш массив как новое значение.

Однако похоже, что вы пытаетесь обновить определенное сообщение как прочитанное, которое немного сложнее. Итак, здесь есть два препятствия:

1: Фактически вы обновляете messages.0.read

Если вы выполните array('$set' => array( 'messages.0.read' => 1 ) ), вы обновите правильный элемент. Следуйте этой цепочке, messages - это объект javascript, и вы хотите обновить свойство 0. Свойство 0 само по себе является объектом javascript, который содержит свойство read, которое вы хотите обновить.

Вы видите, как вы обновляете messages.0.read?

Это приводит нас к проблеме № 2.

2: 0 - проблема для вас

Если вы посмотрите на то, как вы структурировали данные в Mongo, объект сообщений действительно под-par. "0" и "1" в настоящее время действуют как "идентификаторы", и они не очень полезны. Лично я бы структурировал ваши объекты с фактическими идентификаторами вместо "0" или "1".

Итак, ваши объекты выглядят следующим образом:

{
   "_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"
}

Теперь вы выполните команду update:

array('$set' => array( 'messages.ABCDZZZ.read' => 1 ) )

Эта структура упрощает обновление определенного сообщения или определенной части сообщения.

Ответ 2

Если вы хотите сохранить структуру массива для различных целей, вы можете использовать оператор Positional. Это позволяет вам использовать функции массива ($ pop, $push и т.д.), Одновременно имея возможность обновлять элементы, находящиеся в неизвестной позиции массива.