【问题标题】:mongoose remove does not remove all documentsmongoose remove 不会删除所有文档
【发布时间】:2015-09-21 17:27:52
【问题描述】:

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

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);
});

结果:未捕获的 AssertionError:预期 [ Array(1) ] 的长度为 0 但得到了 1

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

【问题讨论】:

    标签: javascript node.js mongodb mongoose mongodb-query


    【解决方案1】:

    虽然在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'});
              }
          }
        }
    );
    

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

    异步库允许回调传递,因此您无需控制每个阶段。任何错误都会立即转到结束块,以及每个阶段的结果。另请查看parallel,而不是这种情况,因为一个阶段不依赖于另一个阶段首先完成。

    【讨论】:

    • 我错过的一件事是,我需要为每个已删除的文档触发预“删除”挂钩,并且 Model.remove() 不会触发这些。
    • @Iralution 我实际上只是向您展示了一种方法来检查您错过的其他条件,即“未找到”,当两个修改计数(由回调返回)均为 0 时会发生这种情况。我确实倾向于修补该功能,但完整的定义是Array.prototyp.reduce,即results.reduce(function(p,n) { return p+n })
    • @Iralution 如果不在您的问题中,那么您不会得到这样的答案。人们只能回答你提出的问题。如果您还有其他问题,请发帖another question
    猜你喜欢
    • 2019-06-05
    • 1970-01-01
    • 2017-05-07
    • 2019-07-16
    • 1970-01-01
    • 2014-02-20
    • 2022-01-08
    • 2011-01-11
    • 1970-01-01
    相关资源
    最近更新 更多