Обновление поля во вложенных документах в mongodb php

0

Я использую MongoDB с PHP-драйвером, поэтому для удобства я напишу запрос с этим синтаксисом, я хотел бы найти более элегантное решение, которое я нашел сегодня для следующей проблемы.

У меня есть эта коллекция "История" с вложенным документом:

История коллекции:

{  
   "_id":"Story1",
   "title":null,
   "slug":null,
   "sections":[  
      {  
         "id_section":"S1",
         "index":0,
         "type":"0",
         "elements":[  
            {  
               "id_element":"001",
               "text":"img",
               "layout":1
            }
         ]
      },
      {  
         "id_section":"S2",
         "index":0,
         "type":"0",
         "elements":[  
            {  
               "id_element":"001",
               "text":"hello world",
               "layout":1
            },
            {  
               "id_element":"002",
               "text":"default text",
               "layout":1
            },
            {  
               "id_element":"003",
               "text":"hello world 3",
               "layout":"2"
            }
         ]
      }
   ]
}

Предполагая, что вы хотите изменить значение элемента с id_element => 002, присутствующим в разделе с id_section => S2 Story с помощью _id => Story1

Решение, которое я нашел сейчас, это найти "позицию" элемента 002 и сделать следующее

1]

$r=$m->db->plot->findOne(array("_id" => 'Story1',
                                        "sections.id_section"=>'S2'),
                                        array('_id'=>false,'sections.$.elements'=>true));

2]

foreach($r['sections'][0]['elements'] as $key=>$value){
    if($value['id_element']=='002'){
        $position=$key;
        break;
    }

3]

$m->db->story->update(array('_id'=>'Story1','sections.id_section'=>'S2','sections.elements.id_element'=>'002'),
                array('$set'=>array('sections.$.elements.'.$position.'.text'=>'NEW TEXT')),
                array('w'=>1));

Повторяю, я не думаю, что это элегантное решение, и я заметил, что это обычная проблема.

Спасибо за помощь.

Теги:

1 ответ

1

Вы не можете использовать $ для соответствия нескольких уровней вложенных массивов. Вот почему не рекомендуется встраивать массивы в MongoDB, если вы ожидаете поиска по свойствам где-нибудь глубже, чем массив верхнего уровня. Альтернативы для фиксированной структуры документа должны знать, какие позиции во всех, кроме одного из массивов, которые вы хотите обновить (или получить документ и узнать индексы, как вы это делаете) или получить документ, обновить его в клиент, и повторно вставьте его.

Другой вариант - переосмыслить, как данные моделируются как документы в MongoDB, так что вложенные массивы не происходят/В вашем случае история представляет собой набор разделов, который представляет собой набор элементов. Вместо создания документа истории вы могли бы представить историю несколькими документами нескольких разделов. В документах разделов будет указано общее значение поля, чтобы указать, что они принадлежат к одной и той же истории. Приведенное выше обновление было бы возможно в качестве обновления одного документа раздела с использованием оператора $ positional для сопоставления и обновления правильного элемента.

  • 0
    Я думаю, что вы правы, на самом деле, изначально я все устроил так, как вы предлагали. Я постараюсь реорганизовать коллекции, еще есть время :)

Ещё вопросы

Сообщество Overcoder
Наверх
Меню