javascript - mongoose remove 不会删除所有文档

标签 javascript node.js mongodb mongoose mongodb-query

我有2个集合(User和Offer),我使用异步进行一系列操作,但最后一个文档没有被删除。

async.series([
  function (callback) {
    User.findOne({_id: req.user._id}, function (err, result) {
      if (err) {
        return callback(err);
      }
        user = result;
        callback();
      });
    },
    function (callback) {
      Offer.find({_owner: user._id}, function (err, offers) {
        if (err) {
          return callback(err);
        }
        var i = offers.length;
        while (i--) {
          var offer = offers[i];
          Offer.remove(offer, function (err) {
            return callback(err);
          });
        }
        callback();
      });
    },
    function (callback) {
      User.remove(user, function (err) {
        if (err) {
          return callback(err);
        }
      });
      callback();
    }
    ], function (err) {
      if (err) {
        return res.status(503).json({message: err});
      }
      res.status(200).json({message: 'User and offers successfully deleted'});
    });

我打开了 mongoose 调试,发现该用户的 8 个文档被删除(如预期)。消息示例:

Mongoose: users.remove({ active: true, role: 'user', favoredOffers: [], 
salt: 'qIADYcMS3SiAuF3M007E9g==', hashedPassword: '**', emailVerified: true, 
name: 'Test', email: 'test1@test.com', emailVerificationToken: '***', 
updatedAt: new Date("Mon, 21 Sep 2015 00:52:58 GMT"), 
createdAt: new Date("Mon, 21 Sep 2015 00:52:58 GMT"), 
_id: ObjectId("55ff54ea1d6201ff42ea0045") }) { 
safe: { w: 'majority', wtimeout: 10000 } }

当我运行测试时,结果是,这个文档仍然存在。起初,我认为我的测试运行得太快(async.waterfall),但后来我切换到 async.series,行为仍然存在,当我查看 test-db 时,文档仍然存在。

测试代码:

it.only('should allow deleting my account and all my offers if my password was right', function (done) {
    async.series([function (callback) {
        login(server, server.delete('*url*'), 'test@test.com', 'testpwd1', function (server) {
            server
                .send({password: 'testpwd1'})
                .expect(200)
                .end(callback);
        });
    }, function (callback) {
        User.findOne({email: 'test1@test.com'}, function (err, user) {
            callback(user ? new Error('user was still found in mongo') : null); //misuse not found user as 'error'-object
        });
    }, function (callback) {
        Offer.find({_owner: user1._id}, function (err, offers) {
            expect(offers).to.have.length(0);
            callback();
        });
    }], done);
});

结果:未捕获断言错误:预期 [ Array(1) ] 的长度为 0,但得到了 1

我是否遗漏了什么或者我不理解 mongdb 的行为。

最佳答案

虽然这些操作是按照 async.series 中分割的操作串行调用的,这里的问题是while循环不是异步控制的,因此在所有删除完成之前会调用移动到下一个阶段的回调。

您可以使用 async.whilst 控制来自 .remove() 的回调操作,但这太过分了,因为您实际上应该直接向 .remove() 发出“查询”而不是尝试使用 .find() 返回的列表:

async.series(
    [
        function (callback) {
          Offer.remove({ "_owner": req.user._id}, callback);
        },
        function (callback) {
          User.remove({ "_id": req.user._id },callback);
        }
    ],
    function (err,results) {
      if (err) {
          res.status(503).json({message: err});
      } else {
          if ( Array.sum(results) == 0 ) {
              res.status(404).json({message: 'User not found'});
          } else {
              res.status(200).json({message: 'User and offers successfully deleted'});
          }
      }
    }
);

当然,如果删除操作的结果没有删除任何内容,那么您就知道输入与用户不匹配。

异步库允许回调传递,因此您无需控制每个阶段。任何错误以及每个阶段的结果都会立即进入结束 block 。另请参阅 parallel 相反,在这种情况下,一个阶段不依赖于另一个阶段先完成。

关于javascript - mongoose remove 不会删除所有文档,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32686189/

相关文章:

javascript - 根据选中的复选框显示/隐藏部分

node.js - 如何在 VS Code 中调试 vue js 应用程序?

node.js - 播放音频-React/NodeJS/MongoDB- GridFS

javascript - jQuery - 字符计数器不适用于粘贴事件

javascript - 如何使菜单在更改浏览器或缩放时保持不变并且不移动

node.js - 蒙戈错误: failed to connect to server in Node-RED

mongodb - 在Go中使用mgo找出插入对象的结果

ruby-on-rails - MongoDB Rails3.2 数据库命令 'create' 失败

JavaScript : can't get json elements from a Json File

node.js - 将redis.get分组2ms,然后通过mget执行