PHP / MongoDB: обновить значение в массиве - PullRequest
14 голосов
/ 17 декабря 2010

У меня есть следующий объект 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"
}

Как мне установить «чтение» на 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"
}

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

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

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

Ответы [ 2 ]

17 голосов
/ 17 декабря 2010

Если вы читаете свою команду, вы на самом деле говорите: "ОБНОВЛЕНИЕ ГДЕ uname = Eamorr3 SET сообщения, равные этому массиву (id = blah, read = 1)"

Когда вы делаете $set на 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, объект messages действительно не соответствует. «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"
}

Теперь ваша команда обновления становится такой:

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

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

2 голосов
/ 23 июня 2011

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...