自动定期旋转MongoDB集合

huangapple go评论73阅读模式
英文:

Rotate MongoDb collection automatically in a periodic manner

问题

假设我有一个Mongo集合("resultData")。我希望每个月进行集合轮换(类似于日志轮换或归档),并自动将旧集合重命名为"{{old_collection_name}}_{{month_year}}"。

这将帮助我保留所有数据,而不会增加集合的大小。

注意:我正在使用Golang进行开发。

英文:

Let's say I have a mongo collection ("resultData"). I want that every month collection rotation happens (similar to log rotation or archiving) and automatically rename the old collection to "{{old_collection_name}}_{{month_year}}."

This will help me to keep all data without increasing the size of the collection.

NOTE: I am using golang for development.

答案1

得分: 1

在MongoDB中,集合在使用之前不需要存在:你可以向一个尚不存在的集合插入数据,它会自动创建。

因此,一个简单且自动的解决方案是始终使用一个以当前月份生成的集合名称。结果,一旦新的月份开始(以该月份命名),文档将被插入到一个新的集合中。

下面是一个实现这个逻辑的简单助手函数:

func getResultColl(db *mongo.Database) *mongo.Collection {
    name := "resultData_" + time.Now().Format("01_2006")
    return db.Collection(name)
}

本月(2022年11月),该函数返回一个名为resultData_11_2022的集合。下个月,返回的集合名称将是resultData_12_2022

使用方法:

var db *mongo.Database // 初始化你的Mongo DB

c := getResultColl(db)

if _, err := c.InsertOne(ctx, resultData); err != nil {
    // 处理错误
}

提示:如果将年份放在月份之前,那么集合的字母顺序将与时间顺序相同。因此,我建议使用"2006_01"格式(布局)代替"01_2006"

还要注意,一个集合中有很多文档并没有问题。你可以简单地将月份作为文档的一个字段,并且如果需要的话,可以通过月份对结果进行过滤,使用索引不会变慢。如果你还存储了时间戳或使用ObjectId作为_id,甚至可以在不添加额外字段的情况下完成这个操作。

英文:

In MongoDB collections do not need to exist prior to using them: you can insert into a collection that does not yet exist, and it will be created automatically.

So a simple and automatic solution is to always use a collection whose name is generated using the current month. As a result, documents will be inserted into a new collection once a new month starts (named after the month).

Here's a simple helper that implements this logic:

func getResultColl(db *mongo.Database) *mongo.Collection {
	name := "resultData_" + time.Now().Format("01_2006")
	return db.Collection(name)
}

This month (2022 November) this function returns a collection whose name is resultData_11_2022. In the next month, the name of the returned collection will be resultData_12_2022.

Using it:

var db *mongo.Database // initialize your Mongo DB

c := getResultColl(db)

if _, err := c.InsertOne(ctx, resultData); err != nil {
	// Handle error
}

Tip: if you move the year in front of the month, then the alphabetical order of the collections will be identical to the chronological order. So I suggest to use "2006_01" format (layout) instead of "01_2006".

Also note that there's nothing wrong having many documents in a collection. You could simply add the month as a field to the documents, and you can filter the results by month if you need, with an index it won't be slower. If you also store the timestamp or use an ObjectId as the _id, you can even do this without adding the month as an extra.

huangapple
  • 本文由 发表于 2022年11月30日 13:29:34
  • 转载请务必保留本文链接:https://go.coder-hub.com/74623247.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定