在我当前的项目中,我们使用Mongo存储许多文档(大约1000亿美元)。 如何使用字段_id删除一半的最旧文档,因为如果使用索引字段“时间戳”,此操作将在约3年后以当前速度完成。
这是指向MongoDB用户Google网上论坛帖子的链接,该帖子讨论了基于时间戳生成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-Extractinsertiontimesfromid,而不是具有aseparatetimestampfield 。
取自帖子中的示例,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")
Run Code Online (Sandbox Code Playgroud)
使用以上公式,您可以从任何日期创建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}})
Run Code Online (Sandbox Code Playgroud)