Проблема не в том, чтобы сделать это, а в том, чтобы сделать это эффективно.Это сценарий, который вычисляет одну часть большего кэша по требованию, тогда все документы должны идти в основную коллекцию.
Я использую агрегат для вычисления этих маленьких частей.Агрегат не может доставить результат порциями, поэтому, чтобы избежать возможного будущего нехватки памяти, я просто $out
результат агрегата во временную коллекцию, я полагаю, что таким образом Монго может обрабатывать любой объем данных внутри, время длярасчет не является проблемой.
Как $out
удалить старые данные коллекции, я не могу просто записать в основную таблицу напрямую.В будущем это не будет проблемой https://jira.mongodb.org/browse/SERVER-12280, но до тех пор мне нужен подход.
Итак, у меня есть коллекция tmp, и я хочу эффективно объединить ее с основной коллекцией.Помните, что mongo eval и copyTo устарели и больше не существуют.
Некоторые люди скажут: «Переберите все документы tmp и вставьте еговнутри основной ".Да, но это будет включать отправку каждого документа монго (может быть огромным) на php, а затем отправку php обратно на монго (сокет tcp или unix не имеет значения). Это пустая трата, чтобы загрузить документ на язык программирования для повторной загрузки.в базу данных, если у вас есть 10 ГБ документов, вы просто тупо сгенерировали 20 ГБ трафика.
Некоторые другие предложат использовать $ lookup, чтобы получить объединенный агрегат, а затем $ до финальногоколлекция".Чувак, если вы присоединитесь таким образом к коллекции tmp 1 ГБ и основной коллекции 100 ГБ, вы будете записывать 101 ГБ на диск, так что это бесполезно.
Другим подходом может быть выполнение:
db.out.find().forEach(function(doc)
{db.target.insert(doc)})
, и это будет обработано внутри, но я не могу выполнить такой фрагмент из PHP.Этот класс http://php.net/manual/es/class.mongodb-bson-javascript.php не имеет абсолютно никакого примера чего-то полезного.Может быть, можно обмануть mapReduce, чтобы выполнить это?Я не знаю.
1.Первое темное решение , чтобы избежать ограничений на mongo-php-драйвер:
$r = shell_exec('mongoexport -d samedatabase -c out | mongoimport -d samedatabase -c target');
Съешь этот монго xD.Все еще загрузка данных для загрузки снова, но гораздо более эффективная, чем передача всех документов через php.mongoimport предупредит о дублированных ключах, если таковые имеются.
2.Второе темное решение
$r = shell_exec('mongo samedatabase --eval "db.out.find().forEach(function(doc) {db.target.insert(doc)})"');
Это позволит управлять всем внутренне с меньшими накладными расходами, но я считал, что eval
заблокирует базу данных во время операции, но я не совсем уверен в новых версиях.
Я застрял: v какое-то предложение от кого-то более творческого, чем я?Спасибо!