Техническая информация. Я использую tokumx (блокировка уровня документа поддержки) и php.
Структура документа похожа на
{
"accounts": [
{
"username": "1",
},
{
"username": "2",
}
],
"site": "test.com"
}
Ситуация:
В большинстве случаев мне нужны только первые учетные записи x из массива "учетные записи".
В считанные минуты эти первые учетные записи x будут удалены из массива "учетные записи" в документе.
Компромисс, который я могу сделать:
извлеките "учетные записи".
{
"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
оператора $push
довольно забавно. Существует модификатор $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"}})
Чтобы получить только первые хэлементы массива, вы можете использовать оператор $ slice в проекционной части вашего запроса, например,
db.accounts.find({},{ accounts : { $slice: 5 }})
или в findAndModify добавьте
fields: { accounts : { $slice: 5 }}
array( 'accounts' => array('$slice' => 5))
спасибо!