下面是我的示例Json消息,它的时间戳格式为YYYY-MM-DDThh:mmTZD(例如2015-08-18T22:43:01-04:00)
我也有一个TTL索引设置30天,但我的数据没有被删除。我知道Mongodb使用ISODate("2015-09-03T14:21:30.177-04:00")格式,但这是绝对必要的吗?我可以对我的索引做什么修改来使TTL工作。
我们在多个集合下有数百万个文档,我们时不时地会耗尽空间。
JSON:{
"_id" : ObjectId("55d3ed35817f4809e14e2"),
"AuditEnvelope" : {
"TrackingInformation" : {
"CorelationId" : "2703-4ce2-af68-47832462",
"Timestamp" : "2015-08-18T22:43:01-04:00",
"LogData" : {
"msgDetailJson" : "[Somedata here]"
}
}
}
}
指数 "1" : {
"v" : 1,
"key" : {
"AuditEnvelope.TrackingInformation.Timestamp" : 1
},
"name" : "TTL",
"ns" : "MyDB.MyColl",
"expireAfterSeconds" : 2592000
},
MongoDB版本:3.0.1
为了使TTL清理过程与定义的TTL索引一起工作,指定的字段必须包含Date
BSON类型,如TTL索引文档所述。
如果文档中的索引字段不是日期或保存日期值的数组,则文档将不会过期。
您需要将这些字符串转换为BSON日期。这也是一个明智的做法,因为BSON Date的内部存储是一个数字时间戳值,这比字符串占用的存储空间少得多。
转换需要一个更新来"强制转换"到一个日期对象。作为"一次性"操作,这可能最好通过MongoDB shell完成,并使用Bulk Operations来最小化写回数据时的网络开销。
var bulk = db.MyColl.initializeOrderedBulkOp(),
count = 0;
db.MyColl.find({
"AuditEnvelope.TrackingInformation.Timestamp": { "$type": 2 }
}).forEach(function(doc) {
bulk.find({ "_id": doc._id }).updateOne({
"$set": {
"AuditEnvelope.TrackingInformation.Timestamp":
new Date(doc.AuditEnvelope.TrackingInformation.Timestamp)
}
});
count++;
if ( count % 1000 == 0 ) {
bulk.execute();
bulk = db.MyColl.initializeOrderedBulkOp();
}
});
if ( count % 1000 != 0 )
bulk.execute();
也不是BSON $type
操作的目的是匹配"字符串",所以即使你开始转换或改变一些代码,开始在字段中产生BSON日期对象,那么查询只拿起"字符串"值进行转换。
理想情况下,您应该删除已经在"Timestamp"字段上的索引,然后在更新后重新创建它们。这消除了将更新的信息写入索引的开销。您还可以在新索引创建的基础上设置一个前景索引,这也将节省索引本身消耗的一些空间。