Mongoose 过期属性无法正常工作

Posted

技术标签:

【中文标题】Mongoose 过期属性无法正常工作【英文标题】:Mongoose expires property not working properly 【发布时间】:2015-06-14 00:32:39 【问题描述】:

答案

事实证明,当我在 Mongoose 中使用 expires 属性进行测试时,我成功地在数据库中设置了一个 TTL 索引,但是当我在我的 mongoose 架构中更改时间时并没有意识到这一点我需要先从数据库中删除之前的 TTL 索引。

TLDR; - 停止应用并删除您要更改的字段的 TTL 索引(参见下面的 cmets / 答案)

获取索引

调用以下示例中的代码即可: db.sampletexts.getIndexes() 我明白了

[
    
        "v" : 1,
        "key" : 
            "_id" : 1
        ,
        "name" : "_id_",
        "ns" : "test.sampletexts"
    ,
     
        "v" : 1,
        "key" : 
            "createdAt" : 1
        ,
        "name" : "createdAt_1",
        "ns" : "test.sampletexts",
        "expireAfterSeconds" : 5400,
        "background" : true,
        "safe" : null
    
]

所以虽然我指定了 60 秒,但它的设置为 5400?嗯。

第二次更新

Heres a minimal example 我正在尝试运行的内容。我必须在这里遗漏一些东西,因为我实际上将我的模型从我的原始项目复制到了示例中(减去了一些额外的字符串字段),现在文档根本没有过期?请让我感到愚蠢,并意识到我遗漏了一些明显的东西。我想了一秒钟来设置一个间隔来运行文档和当前时间之间的时差检查,然后意识到运行这么多经常会扩展的查询有多糟糕。嗯……

MongoDB v3.0.1 && Mongoose v4.0.1

相关代码在:/routes/index.js


我运行的一些测试值:

整个字段看起来像这样

createdAt:  type: Date, expires: 3600, default: Date.now 

测试 1:(测试 3 次) expires: ’300s’

过期时间: 2:00 && 2:50 && 2:28

测试 2:(测试 2 次) expires: ‘600s'

过期时间: 2:08 && 2:58

测试 3 expires: 600 过期时间:2:55

测试 4 expires: 3600 过期时间: 2:13

更新:

我又回来了,因为我尝试了不同版本的 MongoDB,所以我会尝试不同版本的 Mongoose v3.7.4。不幸的是,我得到了同样的结果。我开始怀疑这是否可能是由我的实际计算机(我在本地主机上运行)引起的问题?我不确定 MongoDB 如何获取/设置/监视其 DateTime,但我假设它必须从我的计算机设置中获取它。有什么好方法可以让我进一步测试/调试吗?


原问题:

好的,我已经查看了其他一些关于 Mongoose 和 MongoDB 的过期文档的答案,但它们似乎是因为

a) 文档没有被删除

b) 它在被指定为

后的某个时间点被删除

我的问题是文档正在被删除,但无论如何都会在 1 分钟后被删除。因此,当我指定时间时,无论何时,它都会在 60 秒后将其删除。我看到 MongoDB 每分钟运行一次检查以删除指定的文档,并且默认为 60 秒,所以我假设 MongoDB 正在确认可过期文档,但没有传递 TTL 参数,我很困惑.任何帮助将不胜感激。

这是我的模型:

var schema = mongoose.Schema(
    user_id: String,
    message: String,
    createdAt:  type: Date, expires: '4h', default: Date.now ,
    location: Object
);

版本:

猫鼬 4.0.1

mongodb 3.0.1(也在 2.6.7 中测试过)

【问题讨论】:

Iirc, expires 接受一个整数作为参数,表示直到过期的秒数。你可能想检查一下。尽管您使用的格式应该是有效的,但问题可能是由它引起的。此外,您可能希望关闭您的节点应用程序,删除相应的 TTL 索引并重新启动您的应用程序。 是的,我也尝试过以下值:300 和 60*5,但没有成功。我在写它时指的是他们的文档。 github.com/Automattic/mongoose/blob/4.0.1/lib/schema/date.js 您是否尝试过停止您的应用、删除 TTL 索引并重新启动您的应用? @adrian_reimer db.sampletexts.getIndexes() 在 MongoDB shell 中为 createdAt_1 索引显示什么? @adrian_reimer 修改您的 Mongoose 架构不会修改现有索引,因此您需要手动删除索引并重新启动您的应用程序以按照 Markus 上面的建议重新创建索引。 db.sampletexts.dropIndex('createdAt_1') 【参考方案1】:

修改 Mongoose 架构不会修改现有索引,因此您需要手动删除 TTL 索引并重新启动应用以使用当前定义重新创建索引。

db.sampletexts.dropIndex('createdAt_1')

【讨论】:

以上是关于Mongoose 过期属性无法正常工作的主要内容,如果未能解决你的问题,请参考以下文章

Mongoose 错误:无法同时更新 __v 和 __v

Mongoose 错误:无法同时更新 __v 和 __v

mongoose 中的 UpdateMany 无法正常工作,但直接在 mongodb 中可以正常工作

MongoDB + Mongoose:独特:真正无法正常工作[重复]

mongoose基本增删改查

无法得到我在 nodejs / mongoose / bluebird 中返回的承诺