3

在我的网络抓取项目中,我需要将前一天抓取的数据从移动mongo_collectionmongo_his_collection

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

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

collection.remove()

它工作正常,但有时当 MongoDBcollection包含超过10k 行时它会中断

建议我一些优化的查询,这将占用更少的资源并完成相同的任务

4

5 回答 5

2

您可以为此使用MapReduce作业。

MapReduce 允许您指定一个输出集合来存储结果。

当你有一个 map 函数以它自己的 _id 作为键发出每个文档和一个 reduce 函数返回值数组的第一个(在这种情况下只是因为 _id 是唯一的)条目时,MapReduce 本质上是一个复制操作source-collection 到 out-collection。

未经测试的代码:

db.runCommand(
           {
             mapReduce: "mongo_collection",
             map: function(document) {
                  emit(document._id, document);
             },
             reduce: function(key, values) {
                  return values[0];
             },
             out: {
                  merge:"mongo_his_collection"
             }
           }
         )
于 2013-08-30T07:21:57.570 回答
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++;
    }
}

这会起作用,但您也可以通过批处理写入来获得更好的性能。为此,从游标构建一个 DBObject 数组,并通过一次插入一次将它们全部写入。

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

于 2014-01-02T18:52:55.673 回答
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可能不是最好的解决方案。我认为您的解决方案没有任何问题-如果您编辑问题以解释“它中断”的含义,这将有所帮助。

于 2013-08-30T08:11:12.313 回答
0

您可以尝试mongodumpmongorestore

于 2013-08-30T07:22:20.380 回答
0

你可以renameCollection直接用它来做。或者,如果在不同的 mongods 上,请使用cloneCollection.

参考:

于 2014-04-11T14:19:01.037 回答