Обновление нескольких встроенных документов в mongoDB

1

Мне нужно обновить несколько встроенных документов в монго с помощью 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.

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

Im думает о наличии такой функции:

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
}

Я могу обновлять сразу несколько "объектов".

  • 0
    Кажется, он будет обновлять только один поддок, так как несколько ссылается на корневой документ .... хммм
Теги:

1 ответ

1
Лучший ответ

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

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

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

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

1.Load document = > update = > save (возможно concurrency)
2.Уформируйте структуру своих документов следующим образом (и обновляйте с помощью одного позиционного оператора):

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

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

  • 0
    Спасибо за ответ. Я бы предпочел избегать дополнительного чтения, поэтому вместо этого я немного изменил макет, чтобы категории стали теперь объектом, а не массивом - см. Редактирование в исходном посте.
  • 0
    @sunebrodersen: Добро пожаловать. Хорошо, это будет работать.

Ещё вопросы

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