将MongoDB Collection移动到另一个Collection的更好方法

时间:2013-08-30 05:07:44

标签: mongodb

在我的网页抓取项目中,我需要将前一天的数据从mongo_collection移到mongo_his_collection

我正在使用此查询来移动数据

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

collection.remove()

它工作正常,但有时当MongoDB collection包含 10k行

时会中断

建议我一些优化的查询,它将占用更少的资源并执行相同的任务

5 个答案:

答案 0 :(得分:2)

您可以使用MapReduce作业。

MapReduce允许您指定用于存储结果的收集。

当你有一个map函数发出每个文件时,它自己的_id作为键,而reduce函数返回值数组的第一个(在这种情况下只是因为_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"
             }
           }
         )

答案 1 :(得分: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

请注意,我只是从头顶输入这两个命令而没有实际测试它们,因此请确保在生产中运行它们之前检查它们。

[编辑]:对不起,我刚才意识到这是你需要定期做的事情。在这种情况下,mongodump / mongorestore可能不是最佳解决方案。 我认为你的解决方案没有任何问题 - 如果你编辑了你的问题来解释你的意思,那么它会有所帮助。

答案 2 :(得分:1)

查询中断是因为您没有限制find()。在服务器上创建游标时,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数组,并使用一个插入一次性写入所有这些数组。

此外,如果在复制时更改了收藏集,则无法保证您将遍历所有文档,因为如果它们的大小增加,最终可能会被移动。

答案 3 :(得分:0)

您可以尝试mongodump& mongorestore

答案 4 :(得分:0)

您可以使用renameCollection直接执行此操作。或者,如果在不同的mongods上,请使用cloneCollection

参考文献: