Node.js 正在更新嵌套文档mongo。并发问题

Node.js 正在更新嵌套文档mongo。并发问题,node.js,mongodb,mongoose,Node.js,Mongodb,Mongoose,我正在为猫鼬的一个看似基本的问题而挣扎 我有一个这样的方法: changeStateOnIncident: function(req, res, next) { Incident.findOneQ({ _id: req.params.id }) .then(function(incident) { if (!incident) { return next(new restify.ResourceNotFoundError("Incident with id " + req.par

我正在为猫鼬的一个看似基本的问题而挣扎

我有一个这样的方法:

changeStateOnIncident: function(req, res, next) {
  Incident.findOneQ({ _id: req.params.id })
  .then(function(incident) {
    if (!incident) { return next(new restify.ResourceNotFoundError("Incident with id " + req.params.id + " not found.")) }
    return incident.addStateChange(req.body)
    .then(function(savedState) {
      return res.json(201, savedState);
    })
    .then(function() {
      var alertOrders = _.map(incident.alertees, function(alertee) {
        return alertee.createAndSendAlert(req.body)
      })
      return Q.allSettled(alertOrders)
      .then(function(results) {
        return incident.save();
      })
    })
  })
  .fail(function(err) {
    return next(new restify.InvalidContentError(JSON.stringify(err)))
  })
},
对于createAndSendAlert和addStateChange,它们的定义如下

我想做的是:

查找与传入的ID匹配的事件。 将状态事件添加到状态更改数组中。 将新添加的更改事件返回给用户。 对于事件中的每个警报对象,循环并将警报添加到警报列表中,警报列表是SMS请求的结果。 别再提那件事了。 不幸的是,我现在的做法是并发写入失败。假设我送两个

{
  _id: "53cc87d0feeb4302007eadbe",
  alertees: [
    {
      _id: "eJ65nfJh_g",
      alerts: [
        {
          "_id": "53cc87d1feeb4302007eadc1",
          "created_at": "2014-07-21T03:24:01.304Z",
          "response": "Sent",
          "state": "First state change",
          "updated_at": "2014-07-21T03:24:06.802Z"
        },
        {
          "_id": "53cc87d2feeb4302007eadc5",
          "created_at": "2014-07-21T03:24:02.348Z",
          "response": "Sent",
          "state": "Emergency",
          "updated_at": "2014-07-21T03:24:06.802Z"
        },
        {
          "_id": "53cc87d6feeb4302007eadcc",
          "response": "Sent"
          "state": "Ended",
        }
      ]
    }
  ],

  states: [
    {
      _id: "53cc87d1feeb4302007eadbf",
      state: "First state change"
    },
    {
      _id: "53cc87d1feeb4302007eadc2",
      state: "Second state change"
    },
    {
      _id: "53cc87d2feeb4302007eadc4",
      state: "Third state change"
    },
    {
      _id: "53cc87d6feeb4302007eadcb",
      state: "Fourth state change"
    }
  ]
}
我认为如果我发送两个状态A和B,A的短信响应在B之前返回,可能会使B试图修改的文档无效。如果状态更改发送得太近,我将丢失对子文档的更改


有什么想法吗?我怎么能重写这个?可能使用更新方法?

嵌套数组是您的问题根源,因为您无法发送原子更新。这是MongoDB中不支持的基本功能。理想情况下,您需要对此进行建模,并消除对嵌套数组的需求。被提醒者是否可以移动到单独的文档中?只是在寻找移除一级阵列的方法。可以将警报对象分离出来,但我不希望这样。那么,什么,警报对象将是警报对象Id的数组?您的并发问题主要在以下步骤中A.加载项,B.修改应用程序内存中的项C.发送回可能已更改的服务器。为了避免在一个请求中更新到服务器,只需更新即可。该问题已在操作员更新文档中公布。因此,理想情况下,可以避免将数组嵌套在其他数组中。对于单独的文档,.update的多参数可能有用。