在我当前的项目中,我们使用 Mongo 来存储大量文档(大约 1000 亿)。 如何使用字段 _id 删除一半最旧的文档,因为如果我使用索引字段“时间戳”,此操作将以当前速度在大约 3 年后完成。
2 回答
这是 MongoDB-User Google Groups 帖子的链接,该帖子讨论了基于时间戳生成 ObjectId: http ://groups.google.com/group/mongodb-user/browse_thread/thread/262223bb0bd52a83/3fd9b01d0ad2c41b
来自帖子:从 Mongo ObjectIds 中提取时间戳在 Mongo 文档“优化对象 ID” http://www.mongodb.org/display/DOCS/Optimizing+Object+IDs#OptimizingObjectIDs-Extractinsertiontimesfromidratherthanhaveaseparatetimestampfield中进行了说明。
取自帖子中的示例,ObjectIds 可以从 Unix 时间中的时间(以秒为单位)创建:
> now = new Date()
ISODate("2012-04-19T19:01:58.841Z")
> ms = now.getTime()
1334862118841
> sec = Math.floor(ms/1000)
1334862118
> hex = sec.toString(16)
4f906126
> id_string = hex + "0000000000000000"
4f9061260000000000000000
> my_id = ObjectId(id_string)
ObjectId("4f9061260000000000000000")
使用上面的公式,您可以从任何日期创建一个 ObjectID,并查询具有较少 ObjectId 的文档。
展望未来,如果您的应用程序将基于时间保存数据并在数据达到一定年龄后删除数据,您可能会发现将文档存储在单独的集合中更好;每天、每周或任何对您的应用程序最有意义的时间范围。删除整个集合所需的开销比删除单个文档要少得多,因为它可以通过单个操作完成。 db.<collection>.remove({query})
将为返回的每个文档执行写入操作,正如您所观察到的,对于大量文档来说,这可能会非常慢。
只需找到中间的_id并删除所有旧条目:
蒙哥壳:
// get total documents count / 2
var c = Math.floor( db.collection.stats()['count'] / 2 )
// find middle id
var mid_id = db.collection.find().skip(c).limit(1)[0]._id
// remove all ids older than the middle one
db.collection.remove({_id:{$lt:mid_id}})