MongoDB 错误:无法使用 limit=0 的可重试写入

Posted

技术标签:

【中文标题】MongoDB 错误:无法使用 limit=0 的可重试写入【英文标题】:MongoDB Error: Cannot use retryable writes with limit=0 【发布时间】:2018-10-21 07:48:41 【问题描述】:

我目前正在使用 express、mongodb (atlas cloud) 和 mongoose 开发我的第一个 node.js rest api,当我尝试发出 .remove 请求时出现此错误:


"error": 
    "name": "MongoError",
    "message": "Cannot use (or request) retryable writes with limit=0",
    "driver": true,
    "index": 0,
    "code": 72,
    "errmsg": "Cannot use (or request) retryable writes with limit=0"

这是我的要求:

router.delete('/:productId', (req, res, next) => 
const id = req.params.productId;
Product.remove( _id: id )
    .exec()
    .then(result => 
        res.status(200).json(result);
    )
    .catch(err => 
        console.log(err);
        res.status(500).json(
            error: err
        )
    ); ;
);

【问题讨论】:

这很奇怪。您实际上是否在mongoose.connect() 上的连接字符串或其他选项上传递了任何特殊内容?我很确定 Atlas 集群都升级到了 MongoDB 3.6(这是可重试写入的来源),但实际上不应该有任何“默认情况下”打开此功能。因此,如果您正在做一些“特别”的事情,那么好奇的人会想知道。 你能在你的问题中实际显示变量的值吗?此外,您发出connect() 的代码也将很有用。以防万一。 我看得很清楚,是的,这就是问题所在,我从 atlas mongoDB 复制的 url 已经在其中 retryWrites=true 最后,问题解决了!非常感谢! 哎哟!可能不应该在控制台的默认“建议”URL 中包含它。我可能会将其作为支持请求,因为我看到其他人在做与您完全相同的事情。 嗨@GonzaloRodriguez,你能确认你的MongoDB Atlas部署版本吗?另外,您使用的猫鼬版本是 v5 及以上版本,还是 v4.11 及以上版本?我刚刚尝试重现此问题,MongoDB Atlas 部署 v3.4 不会在 URL 中显示 retryWrites=true,尽管 v3.6 部署会。 【参考方案1】:

我刚刚将 retryWrites=true 中的 true 更改为 false 并且它起作用了。这是一个好方法吗?或者有更好的方法来解决这个问题?

【讨论】:

这行得通,尽管完全删除 ?retryWrites=true 也对我有用。 根本不是一个好方法。 When using retryRewrites set to true tells the MongoDB to retry the same process again which in fact can help prevent failed connections to the database and operate correctly, so having it turn on is recommended. 见:docs.mongodb.com/manual/core/retryable-writes【参考方案2】:

retryWrites=true 是个好东西,解决这种不兼容问题的方法是使用findOneAndRemove 而不是remove(看起来你正在使用猫鼬)

【讨论】:

【参考方案3】:

findOneAndRemove() 函数会更相应地工作,因为它特定于在函数 .findOneAndRemove(filter, options) 中传递的过滤方法,以删除过滤的对象。尽管如此,如果删除过程被连接中断,retryRewrites=true 将在连接时尝试执行函数。

更多信息here

当使用 retryRewrites 设置为 true 时,告诉 MongoDB 再次重试同一进程,这实际上有助于防止与数据库的连接失败并正确运行,因此建议将其打开。

更多信息here

如果你使用的是 Mongoose 5^ 和 MongoDB 3.6,你的代码最好写成这样:

mongoose.connect('mongodb.....mongodb.net/test?retryWrites=true', (err) => 
if(err)
    console.log("Could not connect to MongoDB (DATA CENTER) ");
    else
        console.log("DATA CENTER - Connected")
    
);// CONNECTING TO MONGODB v. 3.6

router.delete('/:productId', (req, res, next) => 
const id = req.params.productId;
Product.findOneAndRemove( _id: id )//updated function from .remove()
    .exec()
    .then(result => 
        res.status(200).json(
       message: "Product Removed Successfuly"
     );
    )
    .catch(err => 
        console.log(err);
        res.status(500).json(
            error: err
        )
    ); ;
);

【讨论】:

以上是关于MongoDB 错误:无法使用 limit=0 的可重试写入的主要内容,如果未能解决你的问题,请参考以下文章

mongodb 分页(limit)

如何重置mongodb聚合限制

MongoDB(课时16 分页显示)

MongoDB Limit与Skip方法

Python MongoDB Limit

Python MongoDB Limit