【问题标题】:Mongodb (using mongoose) expiresAfterSeconds (TTL) doesn't seem to workMongodb(使用猫鼬) expiresAfterSeconds (TTL)似乎不起作用
【发布时间】:2013-06-16 22:51:39
【问题描述】:

我正在为此使用猫鼬。

我的架构是这样的:

var UsuarioSchema = new Schema({
    email : { type : Email, index : { unique : true}, required : true },
    //some other fields, but not required, hopefully, for this sample code
    test_expira : { type : Date, default : Date.now, index : { expires : 120 }}
});

在 mongodb shell 上运行时,这是我认为重要的信息:

> db.usuarios.getIndexes()
[
    {
        "v" : 1,
        "key" : {
            "_id" : 1
        },
        "ns" : "dbnamehere.usuarios",
        "name" : "_id_"
    },
    {
        "v" : 1,
        "key" : {
            "email" : 1
        },
        "unique" : true,
        "ns" : "dbnamehere.usuarios",
        "name" : "email_1",
        "background" : true,
        "safe" : true
    },
    {
        "v" : 1,
        "key" : {
            "test_expira" : 1
        },
        "ns" : "dbnamehere.usuarios",
        "name" : "test_expira_1",
        "expiresAfterSeconds" : 120,
        "background" : true,
        "safe" : true
    }
]
> new Date();
ISODate("2013-06-12T17:41:43.263Z")
> db.usuarios.findOne({email : 'someemail@gmail.com'});
{
    /* some fields go in here! */
    "email" : "someemail@gmail.com",
    /* some more fields go in here */
    "_id" : ObjectId("51b8b087de01a2ec28000002"),
    "test_expira" : ISODate("2013-06-12T17:31:51.156Z"),
    /* some yet more fields go in here */
    "__v" : 0
}

我还没有测试过它多久不被删除,但即使是文档声明也只有一分钟的开销应该是可以预期的,但对于一个应该只持续 120 秒的文档来说,不会超过 15 分钟。

我不确定如何处理这个问题。非常感谢您的帮助:)

编辑: 正在使用的 mongodb 版本是 v2.4.4 mongoose 的版本是 3.0.3

【问题讨论】:

  • 查看 mongod 日志 - 你看到 TTLMonitor 线程每分钟都在运行吗?
  • 顺便说一句,当您在日志中时,请记下服务器上的时间 - new Date() 为您提供 shell 主机时间,而不是服务器时间。它可能在您的服务器上更早。
  • 我没有发现 TTLMonitor 正在运行的证据。我不确定应该在 mongodb.conf 中的哪个位置指定此配置,以防我必须明确指出它是必需的,我知道我当前的 conf 文件没有指出它......我认为只需添加索引 TTLMonitor线程将自动开始运行。另外,感谢您的回复!
  • 顺便说一句,检查时间。似乎 mongodb 服务器和 webserver 时区不匹配(这是一个 dev vm,所以配置上没有那么多细节)。即使那样,时区差异也不足以证明记录在 9 小时后仍未被删除(时区差异似乎正好是 5 小时)。但我确实相信,由于 ISODate 始终位于格林威治,因此忽略了时差,它只是将日期时间调整为服务器所在的任何时区。我说得对吗?
  • 我的错 - TTLMonitor 不会以默认 logLevel 记录到 mongod 日志。您可以通过在 mongo shell 中键入以下内容来临时提高日志记录并查看它在做什么: db.adminCommand({setParameter:1, logLevel:1}) (几分钟后,您可以通过将 logLevel:1 更改为 logLevel 来设置它:0)。它将显示 TTLMonitor 线程正在寻找要删除的内容以及是否找到任何内容。如果您将其粘贴到此处或 pastebin 中,它应该会显示正在发生的事情。我只是在自己测试它。好的,测试完成 - 它对我来说很好......

标签: node.js mongodb mongoose


【解决方案1】:

我已经测试过这个功能,它在 2.4.4 MongoDB 上运行良好。

仔细查看您的索引后,我意识到问题是一个小错字。

我的有效 TTL 索引:

{
    "v" : 1,
    "key" : {
        "test_expira" : 1
    },
    "ns" : "test.usuarios",
    "name" : "test_expira_1",
    "expireAfterSeconds" : 120,
    "background" : true,
    "safe" : true
}

您的 TTL 索引不起作用:

{
    "v" : 1,
    "key" : {
        "test_expira" : 1
    },
    "ns" : "dbnamehere.usuarios",
    "name" : "test_expira_1",
    "expiresAfterSeconds" : 120,
    "background" : true,
    "safe" : true
}

注意 TTL 索引的正确键名是“expireAfterSeconds”,其中您的键名是“expiresAfterSeconds”。

【讨论】:

  • 我意识到您使用的是猫鼬,而“expires”是在其语法中指定此属性的正确方法。我正在检查 Mongooose 和 MongoDB 索引定义之间的断开连接的位置。
  • 看起来 Mongoose 中的这个错误已在 9 个月前修复 - 更新您的 mongoose 版本? github.com/LearnBoost/mongoose/issues/1132
  • 从 3.2.2 到当前的每个 mongoose 版本都存在此修复程序。您使用的 3.0.3 是第一个添加对 TTL 索引的支持的版本,因此 3.0.3 到 3.2.1 有这个问题。
  • 知道了。太棒了 :) 它实际上在昨晚得到了修复,因为我升级了所有代码以使用更新版本的模块运行(我没有将 express 2.11 升级到 3.X 等,因为与旧代码兼容。
猜你喜欢
  • 2022-01-05
  • 1970-01-01
  • 1970-01-01
  • 2018-08-29
  • 2020-06-23
  • 1970-01-01
  • 2014-04-23
  • 1970-01-01
  • 2023-03-03
相关资源
最近更新 更多