Обновление нескольких встроенных документов в mongoDB - PullRequest
1 голос
/ 06 июня 2011

Мне нужно обновить несколько встроенных документов в монго, используя PHP.Мой макет выглядит следующим образом:

{
  _id: id,
  visits : {
        visitID: 12
        categories: [{
              catagory_id: 1,
              name: somename,
              count: 11,
              duration: 122
              },
              {
              catagory_id: 1,
              name: some other name,
              count: 11,
              duration: 122
              },
              {
              catagory_id: 2,
              name: yet another name,
              count: 11,
              duration: 122
              }]
   }
}

Документ также может иметь более одного посещения.

Теперь я хочу обновить 2 категории, одну с id=1 и name=somename идругие с id=1 и name=some_new_name.Они оба должны включать «считать» на 1 и «длительность» на 45.

Первый документ существует, а второй нет.

Я думаю о такой функции:

function updateCategory($id, $visitID,$category_name,$category_id) {

    $this->profiles->update(
            array(
                '_id' => $id, 
                'visits.visitID' => $visitID,
                'visits.categories.name' => $category_name,
                'visits.categories.id' => $category_id,
            ), 
            array(
                '$inc' =>   array(
                            'visits.categories.$.count' => 1,
                            'visits.categories.$.duration' =>45,
                        ),
            ), 
            array("upsert" => true)
    );  
}   

Но при этом мне нужно вызвать функцию для каждой категории, которую я обновлю.Есть ли способ сделать это за один вызов?

EDIT:

Немного изменил раскладку и сделал "категории" объектом вместо массива.Затем в качестве имени свойства использовали комбинацию "category_id" и "category_name".Как:

categories: {
              1_somename : {
                  count: 11,
                  duration: 122
              },
              1_some other name : {
                  count: 11,
                  duration: 122
              },
              2_yet another name : {
                  count: 11,
                  duration: 122
              },
}

Затем с помощью upsert и чего-то вроде

$inc: {
 "visits.$.categories.1_somename.d": 100,
 "visits.$.categories.2_yet another name.c": 1
}

я могу обновить несколько «объектов» одновременно ..

1 Ответ

1 голос
/ 06 июня 2011

Mongodb в настоящее время не поддерживает многоуровневое обновление массивов ( jira )

Поэтому следующий код не будет работать:

'$inc' =>      array( 
   'visits.categories.$.count' => 1, 
   'visits.categories.$.duration' => 123, 
 ),

Итак, есть несколько решений:

1.Загрузить документ => обновить => сохранить (возможные проблемы параллелизма)
2. Реорганизуйте структуру ваших документов следующим образом (и обновите с помощью одного позиционного оператора):

{
  _id: id,
  visits : [{
        visitID: 12
  }],
  categories: [{
              catagory_id: 1,
              name: somename,
              count: 11,
              duration: 122,
              visitID: 12
              }]
   }
}

3. Ожидание поддержки нескольких позиционных операторов (планирование в версии 2.1 mongodb).
4. Как-нибудь иначе реорганизовать структуру ваших документов, чтобы избежать вложения многоуровневых массивов.

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