2012-04-27 1 views
3

Я работаю над многопользовательским веб-приложением. Необходимо очистить некоторый контейнер пользователей, который может быть довольно большим, имея много документов в коллекции. мне нужно, чтобы иметь возможность удалить множество документов что-то вроде:удалить много документов из mongodb

return self::remove(array('LISTID' => $listId), array('safe' => true)); 

В некоторых случаях может быть много документов, отвечающих этим критериям, что-то вроде 100s тысяч или даже миллионы. Я волнуюсь, что эта операция может занять много времени и отключить сервер. Если есть много документов, то стоит очереди такой операция, чтобы удалить их в автономном режиме что-то вроде псевдокода:

while (there are documents) { 
    delete(1000 documents); 
    sleep(); 
} 

Интересно, как удалить данные с меньшей portios в MongoDB в данном случае. Я также замечаю, что по какой-то причине удаление нескольких строк происходит довольно быстро в mongodb, у нас есть прототип с хранением данных в mongodb, удаление такого количества строк занимает намного больше времени в mysql, но в mysql каждая строка в таблице имеет ссылки на другую таблицу с данными, но даже когда therer не является записями в зависимых таблицах, в mongodb он намного быстрее, в mongodb он хранит все данные в документе, но мне все равно кажется странным. Или, может быть, это лишнее?

спасибо.

+0

Сколько арендаторов у вас есть? Если их нет в тысячах, вы можете иметь коллекцию для каждого арендатора и отбрасывать всю коллекцию (если хотите, вы пытаетесь удалить все данные для одного арендатора). Независимо от того, что вы делаете, это почти наверняка представляет собой автономную, пакетную операцию. – Thilo

+0

Это может быть 10 тысяч тысяч арендаторов и даже больше. Эта операция должна очищать данные одного списка, арендаторы могут иметь несколько списков. – Oleg

ответ

5

Это то, что вам нужно будет сделать в вашем приложении. В PHP вы могли бы f.e. сделать что-то вроде:

$found = false; 
$ids = $collection->find(array('LISTID' => $listId), array('_id' => 1))->limit(1000); 
do { 
    $found = 0; 
    $idsToDelete = array(); // we'll collect all the ids here, so that we can delete them in a batch 
    foreach($ids as $res) 
    { 
     $found++; 
     $idsToDelete[] = $res['_id']; 
    } 
    $collection->remove(array('_id' => array('$in' => $idsToDelete))); 
    sleep(15); 
} while ($found); 

Вы должны сделать действительно уверены, что у вас есть индекс по LISTID, в противном случае find(array('LISTID' => $listId) может сделать вещи очень медленно.

+1

Не существует способа ограничить количество удаленных документов в mongodb, как в некоторой базе данных (например, mysql) в операции удаления. – Oleg

+0

Это единственный способ удалить документы меньшими кусками в mongodb? – Oleg

+0

На данный момент нет ограничений на удаление, так что это действительно единственный способ, о котором я могу думать. – Derick