【问题标题】:I'm getting an error of UnknownReplWriteConcern while posting in mongodb atlas using node js(express)使用节点 js(express) 在 mongodb atlas 中发布时出现 UnknownReplWriteConcern 错误
【发布时间】:2020-08-14 21:56:44
【问题描述】:

MongoDB atlas 中发布数据时出错。

const express = require('express');
const router = express.Router();
const Persons = require('./PersonsSchema');

router.post('/',async(req,res)=>{
     console.log(req.body.Name);
     console.log(req.body.Age);
try{
    const postPerson = await new Persons({

        Name : req.body.Name,
        Age : req.body.Age
    })
    const savePersons = await postPerson.save();
    res.status(200).json(savePersons)
}

catch(err){

    res.json({"err": err})
}
});


module.exports = router;

上面提到的是路由文件。

我的数据张贴在地图集中。但我收到一个错误 发布数据时邮递员中的 UnknownReplWriteConcern。

我的Schema 看起来像

 const mongoose = require('mongoose');

 const PersonSchema  = new mongoose.Schema({ name: String },{ age: String }, {
        writeConcern: {
          w: 'majority',
          j: true,
          wtimeout: 1000
        }
      });

module.exports = mongoose.model('Persons',PersonSchema);

【问题讨论】:

    标签: node.js mongodb express mongoose mongodb-atlas


    【解决方案1】:

    昨天我遇到了这个问题,我搜索了答案并找到了您的问题。 最近我找到了解决方案,它在我的代码中有效,所以我决定与你分享。因此,如果遇到相同问题的人将通过此答案获得正确的解决方案。

    在我们找到答案之前,让我们了解一下写关注点发生了什么。

    从 2012 年的 MongoDB 2.2 开始,MongoDB 中的默认写入问题就一直是 w:1

    在当前的 MongoDB 版本(3.2.6 及更高版本)中,您可以使用三种不同的设置来设置写入关注点:

    • w 设置:在宣布写入成功之前应该有多少节点确认写入。默认为 1,表示主节点的确认就足够了。
    • j 设置:在确认之前是否必须记录写入?默认取决于writeConcernMajorityJournalDefault
    • writeConcernMajorityJournalDefault:如果您为您的写入指定w:majority 写入关注设置而不设置j,那么隐含的j 值是多少?默认为true(写入应在大多数投票节点中被记录在确认之前)。

    还有一个wtimeout setting 来配置MongoDB 在通知客户端写入未被确认之前应该等待写入关注满足多长时间。否则,等待写关注得到满足的写可以永远等待而不是失败。

    这里的特殊设置是w:majority。这意味着写入必须传播到要确认的副本集中的大多数投票节点(以及它们的日志)。在提供良好性能的同时,这可以说是最安全的设置,因为:

    • 它可以防止在发生故障时回滚已确认的写入。
    • 它调节应用程序的吞吐量,使其发送写入的速度不会超过副本集可以处理的速度(由于硬件限制、网络状况等)。

    如您所想,投票节点确实包括仲裁者。因此,在具有主次仲裁器设置的副本集中,w:majority 可能会在以下情况下失败:

    • 某个数据承载节点由于某种原因离线。
    • 由于拓扑现在是 primary-arbiter-offline,因此副本集仍然在线且具有可写主节点。
    • w:1 的写入将照常成功,但这些写入可能会被回滚(因为它没有写入大多数承载投票数据的节点)。
    • 由于仲裁器不携带数据,w:majority 写入将失败(或无限期等待),因为仲裁器被计为投票节点。

    因此,如果您计划在应用程序中使用w:majority,则不建议使用仲裁器。

    请注意,也不建议在分片集群中形成分片的 3 节点副本集中使用仲裁器,因为块移动需要 w:majority。一个分片中的数据承载节点故障将不利于块迁移操作。

    所以这是关于写关注的基本解释, 要修复您面临的错误,您只需从架构中删除 w: 'majority'

    这样

     const PersonSchema  = new mongoose.Schema({ name: String },{ age: String }, {
            writeConcern: {
              j: true,
              wtimeout: 1000
            }
          });
    

    此设置修复了我的UnknownReplWriteConcern 错误并且运行良好。所以希望它也能帮助你。

    【讨论】:

      【解决方案2】:

      当我在 .env 文件中有 MongoDB URL 时遇到了这个问题当我将它从 .env 中取出到服务器文件中时,一切正常,vuex 状态可以更新并且错误消失了。我不知道如何解决这个问题。在服务器文件中包含 db 连接 url 不是一个好习惯,因为我们应该使用 process.env.DB_URL 处理它

      【讨论】:

      • 是的,这解决了我的问题
      【解决方案3】:

      我的 DB_URL 位于 .env 文件中,例如 DB_URL = "full_url"。我得到了同样的错误,但是当我删除引号(“”)它工作正常。 DB_URL = full_url 不带引号。

      【讨论】:

      • 即使我删除了引号,问题仍然存在,所以我只是从 .env 文件中删除了 DB_URL 并且它可以工作。
      • 那你将如何保护你的 DB_URL??
      • 好吧,没关系,这是格式问题,应该没有空格和引号。所以,应该是这样的:DB_URL=yoururlhere
      【解决方案4】:

      我有同样的问题,但我的问题是因为我在连接 uri 末尾有一个额外的空间,这会影响结尾(w=majority)

      【讨论】:

      • 这并不能真正回答问题。如果您有其他问题,可以点击 提问。要在此问题有新答案时收到通知,您可以follow this question。一旦你有足够的reputation,你也可以add a bounty 来引起对这个问题的更多关注。 - From Review
      【解决方案5】:

      ?retryWrites=true&w=majorityv 从 mongo db URL 中删除它 并使用异步

      【讨论】:

      • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
      猜你喜欢
      • 2020-03-08
      • 2020-09-16
      • 2020-07-13
      • 2020-02-26
      • 1970-01-01
      • 1970-01-01
      • 2023-03-20
      • 1970-01-01
      • 2015-08-27
      相关资源
      最近更新 更多