Мне нужно обновить несколько встроенных документов в монго с помощью 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
}
Я могу обновлять сразу несколько "объектов".
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.Устройте структуру своих документов как-нибудь иначе, чтобы избежать вложенности массивов нескольких уровней.