非 ISO 日期格式的 MongoDb TTL 索引

标签 mongodb mongodb-query ttl

下面是我的示例 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类型,如 covered in the documentation对于 TTL 索引。

If the indexed field in a document is not a date or an array that holds a date value(s), the document will not expire.

您需要将此类字符串转换为 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 日期对象,查询也只会选取“字符串”值进行转换。

理想情况下,您应该删除“时间戳”字段上已有的索引,然后在更新后重新创建它们。这消除了使用更新信息写入索引的开销。您还可以设置foreground index build在创建新索引时,这也将节省索引本身消耗的一些空间。

关于非 ISO 日期格式的 MongoDb TTL 索引,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32383344/

相关文章:

java - Mongodb (v2.4.0) $match 聚合不适用于日期范围

javascript - 如何使用 Node js 和 mongoose 创建唯一的 json 元素列表

php - 我们如何在 MongoDB 聚合查询中对各个数组元素求和?

python-3.x - 通过 Python3 和 Boto3 将 TTL 添加到 DynamoDB 记录

redis 键设置为过期实际上没有删除

c# - MongoDB C# 驱动程序和 DateTime 字段

javascript - meteor :仅当值存在时才将字段插入 MongoDB

python - 更新 mongoengine 中的嵌入式文档

mongodb - 忘记了 mongodb 管理数据库凭据。重置一切

hadoop - 我可以使用 Sqoop 为从 HDFS 加载到 Couchbase 的文档设置 TTL 吗?