2013-08-30 5 views
2

В моем веб выскабливание проекта мне нужно переместить предыдущий день Царапины данные из mongo_collection в mongo_his_collectionЛучший способ двигаться MongoDB коллекции в другую коллекцию

Я использую этот запрос для перемещения данных

for record in collection.find(): 
    his_collection.insert(record) 

collection.remove() 

Он работает хорошо, но иногда он ломается, когда MongoDB collection содержит выше 10k строк

Предложите мне некоторый оптимизированный запрос, который займет меньше ресурсов и выполните ту же задачу

+0

Спасибо за предложение, но переименование не поможет, потому что я должен собрать все предыдущие скребковые данные в his_collection –

+0

как об использовании экспорта и импорта монго инструменты ?, экспортировать всю коллекцию и импортировать ее в какую-то другую коллекцию. –

+0

Вы делаете это? Это большая работа для сервера базы данных. – WiredPrairie

ответ

2

Для этого вы можете использовать MapReduce.

MapReduce позволяет указать из-коллекции для хранения результатов в.

Когда вы хав функцию карты, которая излучает каждый документ с его собственным _id, как ключ и уменьшить функцию, которая возвращает первый (и в этот случай только потому, что _id является уникальным) вхождение массива значений, MapReduce - это, по сути, операция копирования из коллекции источника в коллекцию.

Непроверенные код:

db.runCommand(
      { 
      mapReduce: "mongo_collection", 
      map: function(document) { 
        emit(document._id, document); 
      }, 
      reduce: function(key, values) { 
        return values[0]; 
      }, 
      out: { 
        merge:"mongo_his_collection" 
      } 
      } 
     ) 
+0

Единственная проблема заключается в том, что MR изменит документ, вам понадобится функция очистки aq, чтобы вернуть документ в свою прежнюю структуру. – Sammaye

+0

@Sammaye, как выполнить функцию очистки aq. не могли бы вы добавить новый ответ с MR и функцией очистки. Я использую pymongo –

+0

@binit Я не знаю, будет ли полезно выполнять функцию очистки после, вы получите ту же проблему, что и вы сейчас ... – Sammaye

1

Если обе коллекции находятся в одной базе данных, я считаю, что вы ищете renameCollection.

Если нет, то вы, к сожалению, придется делать это вручную, с помощью целевой команды mongodump/mongorestore:

mongodump -d your_database -c mongo_collection 
mongorestore -d your_database -c mongo_his_collection dump/your_database/mongo_collection.bson 

Обратите внимание, что я только что ввели эти две команды из верхней части моей головы, фактически не проверяя их, так убедитесь, что вы проверяете их, прежде чем запускать их в процессе производства.

[EDIT]: извините, я просто понял, что это то, что вам нужно делать на регулярной основе. В этом случае mongodump/mongorestore, вероятно, не лучшее решение. Я не вижу в вашем решении ничего плохого - это поможет, если вы отредактируете свой вопрос, чтобы объяснить, что вы подразумеваете под словом «он ломается».

1

Запрос прерывается, потому что вы не ограничиваете поиск(). Когда вы создаете курсор на сервере, mongod попытается загрузить весь результирующий набор в память. Это вызовет проблемы и/или сбой, если ваша коллекция слишком велика.

Чтобы избежать этого, используйте шлейф/предельный цикл. Вот пример в Java:

long count = 0 

while (true) { 
    MongoClient client = new MongoClient(); 
    DBCursor = client.getDB("your_DB_name").getCollection("mongo_collection").find().sort(new BasicDBObject("$natural", 1)).skip(count).limit(100); 

    while (cursor.hasNext()) { 
     client.getDB("your_DB_name").getCollection("mongo_his_collection").insert(cursor.next()); 
     count++; 
    } 
} 

Это будет работать, но вы получите лучшую производительность, выполнив также операции над записью. Для этого создайте массив курсоров DBObjects и запишите их сразу с одной вставкой.

Также, если коллекция изменена во время копирования, нет никакой гарантии, что вы пройдете все документы, так как некоторые могут оказаться перемещенными, если они увеличиваются в размере.

0

Вы можете использовать renameCollection, чтобы сделать это напрямую.Или, если на разных монгодах, используйте cloneCollection.

Ссылка: