我有以下代码 . 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是否将datetime json字符串转换为BSon日期类型以使TTL索引起作用?
findOne命令的结果
> db.Users.findOne({"_expireAt":{$exists: true}})
{“_ id”:“0”,“UserGuid”:{“Value”:“054f6141-e655-41dd-a9d5-39382d3360ab”},“UserName”:null,“FirstName”:{“Value”:“JORDAN”} ,“LastName”:{“Value”:“ACEVEDO”},“Email”:{“Value”:“JORDAN.ACEVEDO@fake.com”},“__ type”:“AuditDemo.ConsoleApplication.Models.Wss.UserInfo, ConsoleTest App,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null“,”_ expireAt“:”2015-05-31T10:23:15.8979321Z“}>
1 回答
好的,我想出了如何纠正这个日期问题 . 我从JSON.Net获得的日期时间字符串未被存储为BSON日期对象 . 所以我不得不在反序列化的BsonDocument属性上调用BsonDateTime.create()方法并强制它成为BSON日期 . 当它以正确的数据类型存储时,TTL索引按预期工作 .