Mongodb手动填充,doc每天

时间:2014-02-25 22:49:30

标签: mongodb

我有一台24小时运行的服务器每个设备每分钟插入1个文档(因此,每天1440个文档),但它可以更多或更少(如1000或3000个文档/天)。

我需要将它们全部放在每个设备的一个文档中,因为在几个月后,有10个设备将是10个设备* 1440个/天* 60天= 432k个文档(太多无法使用)。

因此,我们的想法是每天将它们放在一起,因此每台设备每天都会有一个文档。

我的第一个想法是每天创建一个文档并在此doc(嵌入)中添加文档,但是,主文档增长太多,mongodb需要重新分配它,因此数据库因重新分配而增长很多。 / p>

我的第二个想法是使用手动填充,创建一个文档,其中嵌入了“1440”空文档,每分钟替换一个空文档为真实的...但我怎么能这样做? $ unset和$ set?问题是它每天都不会是1440个文档,所以我不确定如何在我的情况下使用手动填充。

希望你能帮助我!

非常感谢!

2 个答案:

答案 0 :(得分:0)

首先,一个初步问题 - 为什么你说432k文档太多了?通过适当设计的索引和查询,从具有该数字的MongoDB角度来看,应该没有任何问题。如果您可以更多地说明为什么这么多文档会出现问题,我们可能会更好地帮助解决方案,无论是不同的架构设计还是别的什么。

有一个discussion in the the MongoDB docs about manual padding。正如它在那里提到的那样,如果有大量文档移动,mongod会自动调整集合的填充因子,尽管填充因子限制为4,所以可能对你的情况没有帮助。

在你的情况下更有可能帮助的是usePowerOf2Sizes标志,它使mongod分配大小为2的文档。这确实完成了两件事:

  • 每次移动后都会留出一些额外的空间,以便在下次移动之前进行额外的就地扩展,从而减少移动次数,

  • 它可以更有效地利用磁盘空间。

以下小实验说明了最后一点:

function one(usep2) {

    // set up the collection
    db.dropDatabase()
    db.createCollection('c')
    if (usep2)
        printjson(db.runCommand({collMod: "c", usePowerOf2Sizes: true}))

    // create some docs
    for (var id=0; id<500; id++)
        db.c.insert({_id:id, x:[]})

    // grow them
    for (var i=0; i<500; i++) {
        for (var id=0; id<200; id++) {
            db.c.update({_id:id}, {$push:{x:i}})
        }
    }

    // print stats
    var s = db.c.stats(1024)
    var avg = s.avgObjSize
    var stg = s.storageSize
    print('average size: ' + avg + ' kB, storage: ' + stg + ' kB')
}

两次运行此函数说明了usePowerOf2Sizes标志的效果:

> one(false)
average size: 2.632 kB, storage: 21980 kB

> one(true)
{ "usePowerOf2Sizes_old" : false, "usePowerOf2Sizes_new" : true, "ok" : 1 }
average size: 3.22 kB, storage: 10920 kB

使用该标志,每个文档的平均存储空间更大,但由于更有效地管理空闲列表,整体存储空间更小。

最后,如果您确实选择尝试手动填充,则可以在首次创建文档时包含填充字段,然后立即使用$ unset取消设置,如前面链接的discussion on manual padding所示。但我鼓励您研究所有这些可能性并使用db.c.stats()进行测量。

希望这有帮助!

答案 1 :(得分:0)

可能迟到了,但是......

将它们作为单独的文档插入到Collection1中。然后每天一次获取前一天的所有文档,按设备对它们进行分组,并将它们合并为每个设备一个文档,并将它们保存在Collection2中。

通过这种方式,您无需提前了解每个聚合文档的大小,并且可以充分利用文件空间,因为您确切知道将它们聚合到第二个文件时需要多少空间集合。

Collection1可以是TTL集合并自动删除旧数据。或者你可以简单地每天使用一个集合,并在它被合并到聚合之后放弃昨天的集合。这可能是最快的解决方案,因为收集的速度非常快。