удалить много документов из mongodb

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

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

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

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

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

Спасибо.


person Oleg    schedule 27.04.2012    source источник
comment
Сколько у вас арендаторов? Если их не тысячи, вы можете создать коллекцию для каждого арендатора и удалить всю коллекцию (если хотите, вы пытаетесь удалить все данные для одного арендатора). Что бы вы ни делали, это почти наверняка будет автономной пакетной операцией.   -  person Thilo    schedule 27.04.2012
comment
Это могут быть десятки тысяч арендаторов и даже больше. Эта операция должна очищать данные одного списка, арендаторов может быть несколько списков.   -  person Oleg    schedule 27.04.2012


Ответы (1)


Это то, что вам нужно будет сделать в своем приложении. В 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) может сильно замедлить работу.

person Derick    schedule 27.04.2012
comment
Разве нет способа ограничить количество удаленных документов в mongodb, например, в некоторых базах данных (например, mysql) в операции удаления. - person Oleg; 27.04.2012
comment
Это единственный способ удалить документы меньшими кусками в mongodb? - person Oleg; 27.04.2012
comment
На данный момент нет ограничений на удаление, так что это действительно единственный способ, который я могу придумать. - person Derick; 28.04.2012
comment
Мне кажется, в вашем коде должно быть циклично получение еще 1000 идентификаторов, верно? - person Oleg; 03.05.2012