Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/373.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何从mongoose+;表达_Javascript_Node.js_Express_Mongoose - Fatal编程技术网

Javascript 如何从mongoose+;表达

Javascript 如何从mongoose+;表达,javascript,node.js,express,mongoose,Javascript,Node.js,Express,Mongoose,我用mongoose和express 3创建了一个注册表单 用户可能已经存在该用户名,在这种情况下,我会得到一个err.code 11000(重复密钥)。我应该如何处理现有用户 这就是我现在正在做的…但我不确定检查错误代码是最好的方法: user.save(function(err){ if ( err ) { console.log(err); console.log(err.code); //duplicate key if (

我用mongoose和express 3创建了一个注册表单

用户可能已经存在该用户名,在这种情况下,我会得到一个err.code 11000(重复密钥)。我应该如何处理现有用户

这就是我现在正在做的…但我不确定检查错误代码是最好的方法:

  user.save(function(err){
    if ( err ) {
      console.log(err);
      console.log(err.code);

      //duplicate key
      if ( err.code == 11000 ) {
        req.flash('error', 'User already exists');
        res.redirect('/signup');
        return;
      }
    }

    res.locals.user = user;
    req.session.user = user;
    //res.locals.session = req.session;
    res.redirect('/');
  });
有更好的方法吗?

试试这个:

user.save(function(err){
  if ( err && err.code !== 11000 ) {
    console.log(err);
    console.log(err.code);
    res.send('Another error showed up');
    return;
  }

  //duplicate key
  if ( err && err.code === 11000 ) {
    req.flash('error', 'User already exists');
    res.redirect('/signup');
    return;
  }

  res.locals.user = user;
  req.session.user = user;
  //res.locals.session = req.session;
  res.redirect('/');
});

您不会以这种方式填写错误日志。

我还没有尝试过这种方法,但我认为这样可以避免导致错误:

//look for existing user first
user.findOne({ username: req.body.username }, function(err, user) {
  if ( err ) throw err;

  //existing user found, stop registration
  if ( user ) {
      res.flash('error', "That user already exists");
      res.redirect('/signup');
      return;
  }

  //create new user
  var user = new User({ username: req.body.username });

  user.save(function(err){
   if ( err ) throw err;
      res.flash('info', "Your account has been created");
      res.redirect('/account');
  });
});

最简单的方法是使用逻辑方法

  • 将自动增量值定义为唯一
  • someModal.js

    var someschema = Schema({
        num: {type:Number,unique:true} // increment number 
    });
    var someModal = mongoose.model('someschema', someschema);
    
    async function insertDoc(someModal, lastNumFromDb, newDocToSave) {
    
        try {
            let lastNumFromDb = await someModal.findOne().sort({ _id: -1 }).lean();
            newDocToSave.lastNumFromDb = lastNumFromDb + 1
            let saved = await new someModal(newDocToSave).save();
            return saved;
        } catch (err) {
            if (err.code === '11000') {
                return insertDoc(someModal, lastNumFromDb, newDocToSave)
            }else{
                throw err
            }
        }
    
    }
    
    controller.js

    var someschema = Schema({
        num: {type:Number,unique:true} // increment number 
    });
    var someModal = mongoose.model('someschema', someschema);
    
    async function insertDoc(someModal, lastNumFromDb, newDocToSave) {
    
        try {
            let lastNumFromDb = await someModal.findOne().sort({ _id: -1 }).lean();
            newDocToSave.lastNumFromDb = lastNumFromDb + 1
            let saved = await new someModal(newDocToSave).save();
            return saved;
        } catch (err) {
            if (err.code === '11000') {
                return insertDoc(someModal, lastNumFromDb, newDocToSave)
            }else{
                throw err
            }
        }
    
    }
    

    如果你在2021年来这里,我写了一篇关于这个的文章


    您基本上覆盖了
    create
    insertOne
    函数,并在发生错误之前通过indexscan处理错误。

    看起来非常干净。你对此有什么特别不满意的地方?只是我让数据库抛出了一个错误,而不是先检查用户。这取决于什么能让另一个解决方案在你的情况下成为“更好的方式”。这并不难,但如果这在功能上是正确的,并且它的性能是足够的,并且它是可维护的…?我不想用重复的密钥错误填充错误日志。这不是我所拥有的吗?有什么区别。不管怎样,错误都会出现在日志中…不知道这有什么不同。抱歉@chovy,修改了我的答案一点。-如果错误不是“重复密钥”错误,则会出现第一个条件,并向客户端返回“出现另一个错误”。-如果错误是“重复密钥”错误,则将发生第二个条件错误。-如果没有错误,脚本将按照指示运行。我明白了——谢谢。但我仍然认为会记录错误,因为查询抛出了一个错误。我可以执行user.findOne(..,函数(err,user){if(!user)new user();user.save()});您还可以使用
    .count()
    ,这稍微简洁一些,但不允许在需要时使用返回的数据。Ps,我确实认为mongoose应该有类似
    Model.saveUnique({username:req.body.username},function(err){…})的内容
    处理重复键错误实际上更安全,因为在
    user.findOne()
    读取集合和执行
    user.save()
    之间,另一个请求可能创建了用户。也就是说,存在一种竞争条件,在这种情况下,API可能抛出5xx错误。对于希望用户不存在的表单,只需尝试保存它,然后处理预期的DuplicateKey错误,代码就更少了(不需要
    user.findOne()
    ),并避免了这种竞争条件。如果您希望实体已经存在,那么首先尝试加载它可能更自然。