在 mongodb 3.0(.Net 驱动程序 2.0)中使用 TTL 的文档不会过期
Documents not expiring using TTL in mongodb 3.0 (.Net driver 2.0)
我有以下代码。 EnsureIndexes 由构造函数调用以确保已在 _expireAt 字段上创建 TTL 索引。然后,当通过调用 AddOrUpdateItem 方法插入文档时,它会将未来日期添加到 _expireAt 字段。然而,那个日期过去了,文件永远不会过期。我做错了什么?
private void EnsureIndexes()
{
if (!_indexChecked)
{
// TTL index
var tsk =
MongoCollection.Indexes.CreateOneAsync(Builders<BsonDocument>.IndexKeys.Ascending("_expireAt"),
new CreateIndexOptions() { ExpireAfter = TimeSpan.FromSeconds(0) });
tsk.Wait();
_indexChecked = true;
}
}
public void AddOrUpdateItem(string key, TValue value, TimeSpan timeout)
{
var json = value.ToJson();
dynamic jObject = JObject.Parse(json);
jObject._expireAt = DateTime.UtcNow.Add(timeout);
json = jObject.ToString();
var replacementDocument = BsonSerializer.Deserialize<BsonDocument>(json);
var filter = new BsonDocument("_id", key);
var options = new UpdateOptions {IsUpsert = true};
var tsk = MongoCollection.ReplaceOneAsync(filter, replacementDocument, options);
try
{
tsk.Wait();
}
catch (AggregateException ex)
{
// TODO: Log
throw;
}
}
以下内容随 Mongo 集合上的 getIndices 命令一起返回。
> db.Users.getIndices()
[
{
"v" : 1,
"key":{
“_id”:1
},
"name" : "id",
"ns" : "AuditDemo.Users"
},
{
"v" : 1,
"key":{
“_expireAt”:1
},
"name" : "_expireAt_1",
"ns" : "AuditDemo.Users",
"expireAfterSeconds":0
}
]
>
在我的 AddOrUpdateItem 方法中,我首先将泛型类型序列化为 json,以便能够为 expireAt 添加动态元素。然后我使用 BsonSerializer 将这个修改后的 json 反序列化为 BsonDocument。此时,BsonDocument 是否将日期时间 json 字符串转换为 BSon 日期类型以使 TTL 索引起作用?
findOne 命令的结果
> db.Users.findOne({"_expireAt":{$exists: true}})
{
“_id”:“0”,
"UserGuid":{
"Value":“054f6141-e655-41dd-a9d5-39382d3360ab”
},
"UserName":空,
"FirstName":{
"Value" : "JORDAN"
},
"LastName":{
"Value" : "ACEVEDO"
},
"Email":{
"Value" : "JORDAN.ACEVEDO@fake.com"
},
"__typ" : "AuditDemo.ConsoleApplication.Models.Wss.UserInfo, 控制台测试
应用程序,版本=1.0.0.0,文化=中性,PublicKeyToken=null",
“_expireAt”:“2015-05-31T10:23:15.8979321Z”
}
>
好的,我知道如何更正这个日期问题了。我从 JSON.Net 获得的日期时间字符串没有存储在 BSON 日期对象中。所以我不得不在反序列化的 BsonDocument 属性 上调用 BsonDateTime.create() 方法并强制它成为 BSON 日期。当它以正确的数据类型存储时,TTL 索引将按预期工作。
DateTime expiresDate = new DateTime(DateTime.UtcNow.Ticks, DateTimeKind.Utc).Add(timeout);
var replacementDocument = BsonSerializer.Deserialize<BsonDocument>(json);
replacementDocument["_expireAt"] = BsonDateTime.Create(expiresDate);
var filter = new BsonDocument("_id", key);
var options = new UpdateOptions {IsUpsert = true};
var tsk = MongoCollection.ReplaceOneAsync(filter, replacementDocument, options);
我有以下代码。 EnsureIndexes 由构造函数调用以确保已在 _expireAt 字段上创建 TTL 索引。然后,当通过调用 AddOrUpdateItem 方法插入文档时,它会将未来日期添加到 _expireAt 字段。然而,那个日期过去了,文件永远不会过期。我做错了什么?
private void EnsureIndexes()
{
if (!_indexChecked)
{
// TTL index
var tsk =
MongoCollection.Indexes.CreateOneAsync(Builders<BsonDocument>.IndexKeys.Ascending("_expireAt"),
new CreateIndexOptions() { ExpireAfter = TimeSpan.FromSeconds(0) });
tsk.Wait();
_indexChecked = true;
}
}
public void AddOrUpdateItem(string key, TValue value, TimeSpan timeout)
{
var json = value.ToJson();
dynamic jObject = JObject.Parse(json);
jObject._expireAt = DateTime.UtcNow.Add(timeout);
json = jObject.ToString();
var replacementDocument = BsonSerializer.Deserialize<BsonDocument>(json);
var filter = new BsonDocument("_id", key);
var options = new UpdateOptions {IsUpsert = true};
var tsk = MongoCollection.ReplaceOneAsync(filter, replacementDocument, options);
try
{
tsk.Wait();
}
catch (AggregateException ex)
{
// TODO: Log
throw;
}
}
以下内容随 Mongo 集合上的 getIndices 命令一起返回。
> db.Users.getIndices()
[ { "v" : 1, "key":{ “_id”:1 }, "name" : "id", "ns" : "AuditDemo.Users" }, { "v" : 1, "key":{ “_expireAt”:1 }, "name" : "_expireAt_1", "ns" : "AuditDemo.Users", "expireAfterSeconds":0 } ] >
在我的 AddOrUpdateItem 方法中,我首先将泛型类型序列化为 json,以便能够为 expireAt 添加动态元素。然后我使用 BsonSerializer 将这个修改后的 json 反序列化为 BsonDocument。此时,BsonDocument 是否将日期时间 json 字符串转换为 BSon 日期类型以使 TTL 索引起作用?
findOne 命令的结果
> db.Users.findOne({"_expireAt":{$exists: true}})
{ “_id”:“0”, "UserGuid":{ "Value":“054f6141-e655-41dd-a9d5-39382d3360ab” }, "UserName":空, "FirstName":{ "Value" : "JORDAN" }, "LastName":{ "Value" : "ACEVEDO" }, "Email":{ "Value" : "JORDAN.ACEVEDO@fake.com" }, "__typ" : "AuditDemo.ConsoleApplication.Models.Wss.UserInfo, 控制台测试 应用程序,版本=1.0.0.0,文化=中性,PublicKeyToken=null", “_expireAt”:“2015-05-31T10:23:15.8979321Z” } >
好的,我知道如何更正这个日期问题了。我从 JSON.Net 获得的日期时间字符串没有存储在 BSON 日期对象中。所以我不得不在反序列化的 BsonDocument 属性 上调用 BsonDateTime.create() 方法并强制它成为 BSON 日期。当它以正确的数据类型存储时,TTL 索引将按预期工作。
DateTime expiresDate = new DateTime(DateTime.UtcNow.Ticks, DateTimeKind.Utc).Add(timeout);
var replacementDocument = BsonSerializer.Deserialize<BsonDocument>(json);
replacementDocument["_expireAt"] = BsonDateTime.Create(expiresDate);
var filter = new BsonDocument("_id", key);
var options = new UpdateOptions {IsUpsert = true};
var tsk = MongoCollection.ReplaceOneAsync(filter, replacementDocument, options);