Техническое образование: Я использую Tokumx (поддержка блокировка на уровне документа) и php.
Структура документа такая
{
"accounts": [
{
"username": "1",
},
{
"username": "2",
}
],
"site": "test.com"}
Ситуация:
Большую часть времени мне нужно только первые х аккаунты из массива «учетных записей».
Минуты эти первые х аккаунты извлекаются, они должны быть удалены из массива «accounts» в документе.
Компромисс, который я могу сделать:
извлечь «счета».
{
"username" : "1",
"site": "test.com"},
{
"username" : "2",
"site": "test.com"}
Или переключитесь на MySql (последний вариант).
Это был почти комментарий, но это длинный комментарий с дополнительными пояснениями и приведенным примером. Лично я не очень знаком с Tokumx (как, я просто никогда не использовал его), но у MongoDB есть способ сделать это, и это .findAndModify()
метод.
По сути, вы «обновляете» документ или «удаляете» в этом случае, но у вас есть возможность увидеть либо «предварительно измененную», либо «пост-модифицированную» форму в возвращенном результате.
Итак, чтобы работать с массивом, вы вызываете так:
$doc = $collection->findAndModify(
array(), # Something representing the "query"array(
'$pull' => array( # Basicallly the update
'accounts' => array( 'username' => 1 )
)
),
null, # optional projected fields
array( # this is the "options""new" => FALSE, # which is the default
)
);
И для простого документа:
$doc = $collection->findAndModify(
array( 'username' => 1 ),
array(), # update, doesn't matter
null,
array( "remove" => TRUE )
);
Отметив ваш комментарий, вы удаляете первый n
элементы массива с использованием $push
Оператор достаточно забавно. Eсть $slice
модификатор, который делает это:
$doc = $collection->findAndModify(
array(), # Something representing the "query"array(
'$push' => array( # Basicallly the update
'accounts' => array(
'$each' => array(), # But blank
'$slice' => lengthOfArrayMinusNElements
)
)
),
null, # optional projected fields
array( # this is the "options""new" => FALSE, # which is the default
)
);
Не «супер» атомарный, так как вам нужно знать, «как долго» массив, но это можно сделать. Это кажется странным, я знаю, но вы в основном добавляете «ничего» к массиву, но ограничиваете его длину и удаляете элементы с помощью $slice
, Две формы, одна для проекции, другая — модификатор обновления, как показано на рисунке.
Из структуры не совсем понятно, чего вы хотите достичь, но вы хотите выполнить первую часть findAndModify (). Так что ударить в темноте (mogoshell, так как я не знаю драйвер php)
db.accounts.findAndModify({query: {"site": "test.com", "accounts.username":"2"},
update : {$pull: {"accounts" :{ "username" : "2"}})
Чтобы получить только первые x элементов массива, вы можете использовать $ ломтика оператор в проекционной части вашего запроса, например,
db.accounts.find({},{ accounts : { $slice: 5 }})
или в findAndModify добавить
fields: { accounts : { $slice: 5 }}