Mongodb手动填充,每天文档

Mongodb手动填充,每天文档,mongodb,Mongodb,我有一个24小时运行的服务器,每台设备每分钟向一个集合插入一个文档(因此,每天1440个文档),但它可以或多或少(比如1000或3000个文档/天) 我需要将它们放在每个设备的一个文档中,因为几个月后,拥有10台设备将是10台设备*1440/天*60天=432k个文档(太多了) 所以,我们的想法是每天把它们放在一起,这样每个设备每天都有一个文档 我的第一个想法是每天创建一个文档,并在这个文档中添加文档(嵌入),但是,主文档增长太多,mongodb需要重新分配它,因此数据库会因为重新分配而增长太多

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

我需要将它们放在每个设备的一个文档中,因为几个月后,拥有10台设备将是10台设备*1440/天*60天=432k个文档(太多了)

所以,我们的想法是每天把它们放在一起,这样每个设备每天都有一个文档

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

我的第二个想法是使用手动填充,创建一个包含“1440”个空文档的文档,每分钟将一个空文档替换为一个真实的文档。。但是我该怎么做呢$未设置和$set?问题是它永远不会是每天1440个文档,所以我不确定在我的情况下如何使用手动填充

希望你能帮助我


多谢各位

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

有一个问题。正如上面提到的,如果文档移动很多,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')
}
有了该标志,每个文档的平均存储空间会更大,但由于更有效地管理空闲列表,所以总体存储空间会更小

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


希望这有帮助

可能会迟到来帮忙,但是

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

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


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

因为设备不多,每个设备可能有一个不同的集合,一个每日文档(日期),带有一个数组或条目散列。这将只给您10xdays文档。如果您需要在设备和日期之间进行交叉引用,则使用一个每天包含10个文档的集合,按日期和设备进行索引,并填充一个数组或散列项。@user975033我说的是10,但可能是数千!如果我不知道文档将有多少嵌入文档,我如何每天预填充文档?不确定预填充,但为了使数据库更小,您是否尝试过每天只使用一个条目数组填充一个文档,每个条目在进入时添加到数组的底部。[设备、id、数据..]。每个条目只是添加到数组中。这应该只添加所涉及的字节,没有额外的索引将不会添加额外的数据库空间。@user975033我已经尝试过了,但它会创建重新分配,因此文档必须移动几次,数据库大小增长太快!谢谢你,布鲁斯!我说的是432k,但可能是数百万,问题是如果我需要在几天内报告,那么在这个大集合中(可能是数百万份文档)将找到大约1440*2条记录。我认为,最好的解决方案是按天“分组”,但将1500个文档推到另一个文档中是昂贵的(重新分配额外空间)。我已经尝试过两种尺寸的威力,但这还不够。我将检查您发布的mongodb手动填充链接!好啊请注意,如果使用ensureIndex()为正在搜索的字段编制索引,则在数百万个文档的集合中查找几千条记录会很快。索引当然会占用一些空间。您可以使用类似于索引的分层文档结构来加快访问速度,但您只能对一种搜索执行此操作,而您可以使用多个索引来支持不同类型的高效搜索。
> 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