以下是我的示例Json消息,它的时间戳格式为YYYY-MM-DDThh:mmTZD(例如2015-08-18T22:43:01-04:00)
此外,我有30天的TTL索引设置,但我的数据没有被删除。我知道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
答案 0 :(得分:3)
为了使TTL清理过程能够使用定义的TTL索引,指定的字段必须包含Date
BSON类型,对于TTL索引,covered in the documentation也是如此
如果文档中的索引字段不是date或包含日期值的数组,则文档不会过期。
您需要将此类字符串转换为BSON日期。这也是明智之举,因为BSON Date的内部存储是一个数字时间戳值,这比字符串占用的存储空间少得多。
转换需要更新" cast"到一个约会对象。作为一个"一个关闭"这可能最好通过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日期对象,那么查询只拿起"字符串"转换价值。
理想情况下,您应该将索引放在"时间戳"字段然后在更新后重新创建它们。这消除了使用更新的信息写入索引的开销。您还可以在新索引创建时设置foreground index build,这也将节省索引本身消耗的空间。